package com.ymatou.iapi.optrade.testcase;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.google.common.collect.Lists;
import com.ymatou.iapi.optrade.parameter.enums.BondedAreaEnum;
import com.ymatou.iapi.optrade.parameter.enums.CancelOrderTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.PayStatusEnum;
import com.ymatou.iapi.optrade.parameter.enums.PayTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.ReduceStatusEnum;
import com.ymatou.iapi.optrade.parameter.enums.TerminalSourceEnum;
import com.ymatou.iapi.optrade.parameter.req.PayReq;
import com.ymatou.iapi.optrade.parameter.req.PlaceOrderReq;
import com.ymatou.iapi.optrade.parameter.utill.Utils;
import com.ymatou.iapi.optrade.parameter.vo.OrderGroupVo;
import com.ymatou.iapi.optrade.parameter.vo.OrderItemVo;
import com.ymatou.iapi.optrade.parameter.vo.OrderVo;
import com.ymatou.iapi.optrade.parameter.vo.PrepaidCardVo;
import com.ymatou.iapi.optrade.resp.Order;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.service.IdCardService;
import com.ymatou.iapi.optrade.service.PayReqCall;
import com.ymatou.iapi.optrade.service.PrepaidCardService;
import com.ymatou.iapi.optrade.service.RefundService;
import com.ymatou.iapi.productmanager.parameter.product.AddSellerProductRequest;
import com.ymatou.iapi.productmanager.service.AddSellerProductCall;
import com.ymatou.iapi.productmanager.service.SaveCatalogPackageListCall;
import com.ymt.core.tool.FormatUtil;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P2;
import com.ymt.utils.tag.P3;
import com.ymttest.business.service.AccountCallServiceV2;
import com.ymttest.business.service.PayGateWayCallService;
import com.ymttest.business.service.ProductManagerCallServiceV2;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceAnliOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceEngageOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.business.service.YMTTrading.TradingProductVo;
import com.ymttest.business.service.shenqi.DGSQBaseService;
import com.ymttest.business.service.shenqi.GodmchManageCallService;
import com.ymttest.business.service.shenqi.SqTradingCallService;
import com.ymttest.database.model.MPayment;
import com.ymttest.database.model.YmtCatalogsI;
import com.ymttest.database.model.anlihui.Settlement;
import com.ymttest.database.sharding.db.sharding.model.MainOrderPo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailPo;
import com.ymttest.database.sharding.db.sharding.model.OrderDetailSubPo;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.OrderStatusLogPo;
import com.ymttest.database.sharding.db.sharding.model.PaymentDetailPo;
import com.ymttest.database.sharding.db.sharding.model.PaymentPo;
import com.ymttest.database.sharding.db.sharding.model.UserRefundFundDetailPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.database.sharding.db.sqlwapper.OrderWapper;
import com.ymttest.database.sqlwapper.PayGateWayWapper;
import com.ymttest.database.sqlwapper.YmtCatalogsIWapper;
import com.ymttest.database.sqlwapper.anlihui.SettlementWrapper;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.MapUtil;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.constant.ECode;

/**
 * 支付接口 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_OrderPay {

	private static PayReq payReq;
	private static PayReqCall payReqCall;
	
	private static OrderShardingWapper database = new OrderShardingWapper();
	private static SettlementWrapper settlementWrapper = new SettlementWrapper();
	
	private static long userId = 20238699;
	
	private static Long sellerId = Long.valueOf(EnvSetup.getData("autotest_seller1"));
	private static String sellerName = String.valueOf(EnvSetup.getData("autotest_sellerName1"));

	// 代购神器测试固定汇率
	private static String settleRate = PayGateWayCallService.HKExchangeRate;
//	private static long autotest_goodsOwnerId = Long.valueOf(EnvSetup
//			.getData("autotest_goodsOwnerId"));

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("新增支付接口");
		
		//防止商家余额不足，导致退款失败
		String accountid1;
		try {
			accountid1 = AccountCallServiceV2.getAccountId(24635724);
			AccountCallServiceV2.resetAccount(accountid1, new BigDecimal(
					9000000), new BigDecimal(0));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Before
	public void caseUp() {
		payReq = new PayReq();
		payReqCall = new PayReqCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(payReqCall.getOpurl());
		
		database.activeDeadCommunicationsLink(database);
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	@SuppressWarnings("deprecation")
	public static String getPackageCatalogId() throws Exception {

		SaveCatalogPackageListCall saveCatalogPackageListCall = new SaveCatalogPackageListCall();
		int packageId1 = saveCatalogPackageListCall
				.callAndGetReturnData(
						MapUtil.hashMap(
								"ProductPackageList[0]->SubCatalogName",
								"测试组合001测试组合001",
								"ProductPackageList[0]->Price", 20,
								"ProductPackageList[0]->Num", 30,
								"ProductPackageList[0]->Sku", "test",
								"ProductPackageList[0]->ProductCode",
								"procodetest")).getJSONObject("Data")
				.getJSONArray("SubCatalogIdList").getInt(0);

		int packageId2 = saveCatalogPackageListCall
				.callAndGetReturnData(
						MapUtil.hashMap(
								"ProductPackageList[0]->SubCatalogName",
								"测试组合002测试组合001")).getJSONObject("Data")
				.getJSONArray("SubCatalogIdList").getInt(0);

		int packageId3 = saveCatalogPackageListCall
				.callAndGetReturnData(
						MapUtil.hashMap(
								"ProductPackageList[0]->SubCatalogName",
								"测试组合003测试组合001")).getJSONObject("Data")
				.getJSONArray("SubCatalogIdList").getInt(0);

		int packageId4 = saveCatalogPackageListCall
				.callAndGetReturnData(
						MapUtil.hashMap(
								"ProductPackageList[0]->SubCatalogName",
								"测试组合004测试组合001")).getJSONObject("Data")
				.getJSONArray("SubCatalogIdList").getInt(0);

		AddSellerProductRequest addProdReq = ProductManagerCallServiceV2
				.initAddSellerProductRequest(288484);
		// 带上套装
		addProdReq.getProduct().getCatalogList().get(0)
				.setSubCatalogIdList((Arrays.asList(packageId1, packageId2)));
		addProdReq.getProduct().getCatalogList().get(0).setPackage(true);

		addProdReq.getProduct().getCatalogList().get(1)
				.setSubCatalogIdList((Arrays.asList(packageId3, packageId4)));
		addProdReq.getProduct().getCatalogList().get(1).setPackage(true);

		AddSellerProductCall addSellerProductCall = new AddSellerProductCall();
		addSellerProductCall.setData(addProdReq);
		addSellerProductCall.callService();

		// 获取商品ID
		String productId = ProductManagerCallServiceV2
				.addNewProduct(addProdReq).get("Data").getAsJsonObject()
				.get("ProductId").getAsString();
		// 获取规格ID
		List<String> catalogs = new YmtCatalogsIWapper()
				.selectCatalogsByProductId(productId).stream()
				.map(YmtCatalogsI::getsCatalogId).collect(Collectors.toList());

		return catalogs.get(0);
	}

	/**
	 * 
	 * 组合商品订单
	 * 
	 * @throws Exception
	 * 
	 */
	public static TradingServiceResp placeOrder() throws Exception {

		// 组合商品
		String catalogId = getPackageCatalogId();

		PlaceOrderReq placeOrderReq = TradingCallService
				.buildDemoReq(true);

		OrderItemVo orderItemVo = placeOrderReq.getOrderGroups().get(0)
				.getOrders().get(0).getOrderItems().get(0);

		orderItemVo.setCatalogId(catalogId);
		orderItemVo.setSubProduct(true);

		return TradingCallService.callPlaceOrderService(placeOrderReq);
	}

	/**
	 * 贝海保税订单,指定收件人,年使用额度超过20000
	 * 
	 * @param name
	 * @param logisticsType
	 * @param isEcommerceFlag
	 * @return
	 */
	private static TradingServiceResp placeOrder2(String name,
			LogisticsTypeEnum logisticsType, boolean isEcommerceFlag) {

		PlaceOrderReq placeOrderReq = TradingCallService
				.buildDemoReq(true);

		placeOrderReq.setRecvName(name);

		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setLogisticsType(logisticsType);

		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.getOrderItems().get(0).setBondedArea(BondedAreaEnum.HangZhou);

		placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
				.setEcommerceFlag(isEcommerceFlag);

		return TradingCallService.callPlaceOrderService(placeOrderReq);

	}

	/**
	 * 多买手,多商品,生成多个订单
	 * 
	 * @param isBargainGroup
	 *            是否砍价团订单
	 * @return
	 */
	private static TradingServiceResp placeOrder4(boolean isBargainGroup) {

		return placeOrder4(isBargainGroup, false);

	}

	/**
	 * 多买手,多商品,生成多个订单
	 * 
	 * @param isBargainGroup
	 *            是否砍价团订单
	 * @param canPayDeduct
	 *            是否使用app内立减支付金额
	 * @return
	 */
	private static TradingServiceResp placeOrder4(boolean isBargainGroup,
			boolean canPayDeduct) {

		PlaceOrderReq placeOrderReq = TradingCallService
				.buildStandPlaceOrderReq();

		OrderGroupVo orderGroupVo1 = TradingCallService.createOrderGroupVo(sellerId, sellerName);
		OrderVo orderVo1 = TradingCallService.createOrderVo();
		
		TradingProductVo productVo1 = null;
		TradingProductVo productVo2 = null;
		TradingProductVo productVo3 = null;

		if (isBargainGroup) {

			productVo1 = new TradingProductVo(TestDataManager.getRandomUUID()
					.toString(), TestDataManager.getRandomUUID().toString());
			productVo2 = new TradingProductVo(TestDataManager.getRandomUUID()
					.toString(), TestDataManager.getRandomUUID().toString());
			productVo3 = new TradingProductVo(TestDataManager.getRandomUUID()
					.toString(), TestDataManager.getRandomUUID().toString());
		}

		else {
			productVo1 = TradingProductVo
					.createPro(sellerId, sellerName, 10);
			productVo2 = TradingProductVo
					.createPro(sellerId, sellerName, 10);
			productVo3 = TradingProductVo
					.createPro(sellerId, sellerName, 10);
		}
		
		OrderItemVo orderItemVo1 = TradingCallService.createOrderItemVo(
				productVo1.getProductId(), productVo1.getCatalogId());
		OrderItemVo orderItemVo2 = TradingCallService.createOrderItemVo(
				productVo2.getProductId(), productVo2.getCatalogId());
		OrderItemVo orderItemVo3 = TradingCallService.createOrderItemVo(
				productVo3.getProductId(), productVo3.getCatalogId());

		orderVo1.setOrderItems(Arrays.asList(orderItemVo1, orderItemVo2, orderItemVo3));
		orderGroupVo1.setOrders(Arrays.asList(orderVo1));

		// 买手2 订单组
		long sellerId2 = Long.valueOf(EnvSetup.getData("SellerId"));
		String sellerName2 = String.valueOf(EnvSetup.getData("SellerName"));
		
		OrderGroupVo groupVo2 = TradingCallService.createOrderGroupVo(
				sellerId2, sellerName2);
		OrderVo orderVo2 = TradingCallService.createOrderVo();
		
		TradingProductVo productVo4 = null;
		TradingProductVo productVo5 = null;
		TradingProductVo productVo6 = null;

		if (isBargainGroup) {

			productVo4 = new TradingProductVo(TestDataManager.getRandomUUID()
					.toString(), TestDataManager.getRandomUUID().toString());
			productVo5 = new TradingProductVo(TestDataManager.getRandomUUID()
					.toString(), TestDataManager.getRandomUUID().toString());
			productVo6 = new TradingProductVo(TestDataManager.getRandomUUID()
					.toString(), TestDataManager.getRandomUUID().toString());
		}

		else {
			productVo4 = TradingProductVo.createPro(sellerId2, sellerName2, 10);
			productVo5 = TradingProductVo.createPro(sellerId2, sellerName2, 10);
			productVo6 = TradingProductVo.createPro(sellerId2, sellerName2, 10);
		}
		
		OrderItemVo orderItemVo4 = TradingCallService.createOrderItemVo(
				productVo4.getProductId(), productVo4.getCatalogId());
		OrderItemVo orderItemVo5 = TradingCallService.createOrderItemVo(
				productVo5.getProductId(), productVo5.getCatalogId());
		OrderItemVo orderItemVo6 = TradingCallService.createOrderItemVo(
				productVo6.getProductId(), productVo6.getCatalogId());

		orderVo2.setOrderItems(Arrays.asList(orderItemVo4, orderItemVo5, orderItemVo6));

		groupVo2.setOrders(Lists.newArrayList(orderVo2));
		
		placeOrderReq.setOrderGroups(Arrays.asList(orderGroupVo1, groupVo2));

		return TradingCallService.callPlaceOrderService(placeOrderReq);
	}
	
	/**
	 * 支付完成后（包括第三方支付回调交易完成）,校验订单数据
	 * 
	 * @param paymentId
	 * @param useAccountAmount
	 * @param orderList
	 * @param cmbDiscountAmount
	 * @throws Exception 
	 */
	private void verifyDb(long paymentId, BigDecimal useAccountAmount,
			List<Order> orderList, BigDecimal cmbDiscountAmount) throws Exception {
		verifyDb(paymentId, useAccountAmount, orderList,
				cmbDiscountAmount, null);
	}

	/**
	 * 支付完成后（包括第三方支付回调交易完成）,校验订单数据
	 * 
	 * @param paymentId
	 * @param useAccountAmount
	 * @param orderList
	 * @param cmbDiscountAmount
	 * @param placeEngageReq
	 * @throws Exception 
	 */
	private void verifyDb(long paymentId, BigDecimal useAccountAmount,
			List<Order> orderList, BigDecimal cmbDiscountAmount,
			PlaceOrderReq placeEngageReq) throws Exception {

		// 用户id
		long userId = 0;

		if (null != placeEngageReq)
			userId = placeEngageReq.getUserId();
		else
			userId = payReq.getUserId();
		
		BigDecimal payDeductAmount = BigDecimal.ZERO;
		int cardStatus = ReduceStatusEnum.NO_NEED.getCode();

		// 主订单表
		MainOrderPo actualMainOrder = database.selectMianOrderbyId(payReq
				.getTradingId());

		if (actualMainOrder != null) {
			payDeductAmount = actualMainOrder.getPayDeductAmount() == null ? BigDecimal.ZERO
					: actualMainOrder.getPayDeductAmount();

			// 订单是否使用预付卡
			cardStatus = actualMainOrder.getCardStatus();
		}

		BigDecimal orderDiscount = BigDecimal.ZERO;
		BigDecimal realNeedPayAmount = BigDecimal.ZERO;
		BigDecimal freight = BigDecimal.ZERO;
		BigDecimal totalYmtCouponAmount = BigDecimal.ZERO;
		BigDecimal totalSellerCouponAmount = BigDecimal.ZERO;
		BigDecimal totalCardAmount = BigDecimal.ZERO;
		BigDecimal needPayAmount = BigDecimal.ZERO;
		BigDecimal totalTaxFee = BigDecimal.ZERO;
		BigDecimal totalRebateAmount = BigDecimal.ZERO;
		String payCurrency = null;
		String payment_payCurrency = null;
		Integer customSettlementCurrencyType = null;
		
		BigDecimal[] realNeedPayAmountList = new BigDecimal[orderList.size()];

		Order order = orderList.stream()
				.filter(o -> o.getOrderPo().getGoodsOwnerId() == 0).findAny()
				.orElse(null);

		boolean isShenqiOrder = order == null ? true : false;
		
		if (payReq.getTradeType() == 1) {
			
			totalYmtCouponAmount = orderList.stream()
					.map(o -> o.getOrderPo().getYmtCouponAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalSellerCouponAmount = orderList.stream()
					.map(o -> o.getOrderPo().getSellerCouponAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalCardAmount = orderList.stream()
					.map(o -> o.getOrderPo().getCardAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalTaxFee = orderList.stream()
					.map(o -> o.getOrderPo().getTaxFee())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalRebateAmount = orderList.stream()
					.map(o -> o.getOrderPo().getRebatePaidAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			for (int i = 0; i < orderList.size(); i++) {

				database.clearCache();
				
				OrderPo orderPo = database.selectOrderbyOrderId(
						orderList.get(i).getOrderId());
				orderDiscount = orderDiscount.add(orderPo.getOrderDiscount());
				payCurrency = orderPo.getCurrency();
				freight = freight.add(orderPo.getFreight());
				realNeedPayAmountList[i] = orderPo.getPayableAmount();
				realNeedPayAmount = realNeedPayAmount.add(orderPo
						.getPayableAmount());
				
				customSettlementCurrencyType = orderPo.getCustomSettlementCurrencyType();
			}

			// 该交易需要支付的总金额
			needPayAmount = orderList.stream()
					.map(o -> o.getOrderPo().getTotalPrice())
					.reduce(BigDecimal.ZERO, BigDecimal::add)
					.subtract(payDeductAmount).add(orderDiscount).add(freight).add(totalTaxFee)
					.subtract(totalSellerCouponAmount)
					.subtract(totalYmtCouponAmount)
					.subtract(totalCardAmount)
					.subtract(totalRebateAmount);
			
			if (payReq.getDiscountAfterPay())
				needPayAmount = needPayAmount.subtract(orderDiscount);
			
		} else {
			
			totalYmtCouponAmount = orderList.stream()
					.map(o -> o.getOrderPo().getYmtCouponAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalSellerCouponAmount = orderList.stream()
					.map(o -> o.getOrderPo().getSellerCouponAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalCardAmount = orderList.stream()
					.map(o -> o.getOrderPo().getEarnestCardAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);
			totalTaxFee = orderList.stream()
							.map(o -> o.getOrderPo().getTaxFee())
							.reduce(BigDecimal.ZERO, BigDecimal::add);
			
			for (int i = 0; i < orderList.size(); i++) {

				database.clearCache();
				
				OrderPo orderPo = database.selectOrderbyOrderId(
						orderList.get(i).getOrderId());
				orderDiscount = orderDiscount.add(orderPo.getOrderDiscount());
				
				freight = freight.add(orderPo.getFreight());
				
				realNeedPayAmountList[i] = orderPo.getPayableAmount();
				
				realNeedPayAmount = realNeedPayAmount.add(orderPo
						.getPayableAmount());
				
				orderPo.getGoodsOwnerId();
			}
		
			// 该交易需要支付的总金额，定金不需要运费
			needPayAmount = orderList.stream()
					.map(o -> o.getOrderPo().getEarnestAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add)
					.subtract(payDeductAmount).add(orderDiscount).add(totalTaxFee)
					.subtract(totalSellerCouponAmount)
					.subtract(totalYmtCouponAmount).subtract(totalCardAmount);
		}
		
		// 用户支付的余额
		useAccountAmount = Utils.zeroIfNull(useAccountAmount);

		// 支付类型
		PayTypeEnum type;

		if (BigDecimal.ZERO.compareTo((useAccountAmount)) == 0) {

			type = PayTypeEnum.FULL_THIRD_PARTY;

		} else if (Utils.isBiggerThanOrEqual(useAccountAmount, realNeedPayAmount)) {
			type = PayTypeEnum.FULL_BALANCE;

			// 如果是全余额支付，用户使用的余额等于订单应付的金额
			useAccountAmount = needPayAmount;
		} else {
			type = PayTypeEnum.MIX_PAY;
		}

		// 支付表(payment)
		PaymentPo paymentPo = database.selectPaymentById(paymentId);

		PaymentPo expectedPayment = new PaymentPo();

		expectedPayment.setUserId(userId);
		expectedPayment.setPaymentId(paymentId);
		expectedPayment.setAccountAmount(useAccountAmount);
		expectedPayment.setPayableAmount(needPayAmount);
		expectedPayment.setThirdpartyAmount(needPayAmount
				.subtract(useAccountAmount));

		if (null != placeEngageReq) {

			expectedPayment.setTradeType(2);
			expectedPayment.setPayStatus(PayStatusEnum.CREATE.getCode());
			expectedPayment.setPayType(PayTypeEnum.FULL_BALANCE.getCode());
			payReq.setTradeType(2);
		} else {

			expectedPayment.setTradeType(payReq.getTradeType());
			expectedPayment.setPayStatus(PayStatusEnum.MINUS_BALANCE_SUCCESS
					.getCode());
			expectedPayment.setPayType(type.getCode());
		}

		expectedPayment.setThirdpartyDiscount(cmbDiscountAmount);
		expectedPayment.setPayDeductAmount(payDeductAmount);

		expectedPayment.setRealPaidAmount(realNeedPayAmount);
		expectedPayment.setRetryTimes(0);
		
		//如果订单上面的currency为null，则payment上面的payCurrency为CNY
		if (null == payCurrency || SqTradingCallService.isShengPay(payReq.getPayType()))
			payment_payCurrency = "CNY";
		else
			payment_payCurrency = payCurrency;
		
		expectedPayment.setPayCurrency(payment_payCurrency);

		if (payReq.getPayType() == "6000" || payReq.getPayType() == "6006") {
			
			expectedPayment.setAppName(payReq.getShenqiMpId());

//			String settleCurrency = TradingForDGSQCallService
//					.getMchInfoBySellerId(orderList.get(0).getSellerId()).getCurrency();
			
			Order orderPo = orderList
					.stream()
					.max((o1, o2) -> o1.getOrderPayableAmount().compareTo(
							o2.getOrderPayableAmount())).get();
			
			String settleCurrency = GodmchManageCallService
					.getMchInfoBySellerId(orderPo.getOrderPo().getGoodsOwnerId()).getCurrency();
			
			if (settleCurrency.equalsIgnoreCase("KRW"))
				settleCurrency = "USD";
			
			if (!payment_payCurrency.equalsIgnoreCase("CNY")) {
				
				expectedPayment.setExchangeRate(payReq.getPayAmount().divide(
						realNeedPayAmount, 5, BigDecimal.ROUND_HALF_DOWN)
						.toPlainString());
				settleRate = "1";
			} else {
				expectedPayment.setExchangeRate("1.00000");
			}
			
			expectedPayment.setPaidMerchantNum("WC5c78d78282173");
			
			expectedPayment.setForeignAmount(needPayAmount.divide(
					new BigDecimal(settleRate), 2, BigDecimal.ROUND_DOWN));
			BigDecimal realForeignAmount = SqTradingCallService
					.calRealForeignAmount(expectedPayment.getRealPaidAmount(),
							expectedPayment.getPayableAmount(),
							expectedPayment.getForeignAmount());

			expectedPayment.setSettleCurrency(settleCurrency);
			expectedPayment.setSettleRate(settleRate);
			expectedPayment.setRealForeignAmount(realForeignAmount);
			
			expectedPayment.setShenqiPaymentRmbAmount(payReq.getPayAmount());
		} else if (SqTradingCallService.isShengPay(payReq.getPayType())) {
			
			expectedPayment.setAppName(payReq.getShenqiMpId());
			expectedPayment.setPaidMerchantNum("30057909");
			
			// 渠道结算币种为人民币，标价币种为外币
			if (null != customSettlementCurrencyType && !Utils.nullIsCNY(payCurrency).equalsIgnoreCase("CNY")) {

				BigDecimal exchageRate = DGSQBaseService
						.getCurrencyConfig(Utils.nullIsCNY(payCurrency)).getExchangeRmbRateForTe();
				
				BigDecimal foreignAmount = needPayAmount.multiply(exchageRate).setScale(2, BigDecimal.ROUND_HALF_DOWN);
				expectedPayment.setForeignAmount(foreignAmount);
				
				BigDecimal realForeignAmount = SqTradingCallService
						.calRealForeignAmount(expectedPayment.getRealPaidAmount(),
								expectedPayment.getPayableAmount(),
								expectedPayment.getForeignAmount());
				
				expectedPayment.setExchangeRate(exchageRate.setScale(5).toString());
				expectedPayment.setForeignAmount(foreignAmount);
				expectedPayment.setSettleCurrency("CNY");
				expectedPayment.setSettleRate("1");
				expectedPayment.setRealForeignAmount(realForeignAmount);
				expectedPayment.setShenqiPaymentRmbAmount(payReq.getPayAmount());
				expectedPayment.setPayCurrency(Utils.nullIsCNY(payCurrency));
			} else {
				
				expectedPayment.setExchangeRate("1.00000");
				
				expectedPayment.setForeignAmount(needPayAmount);
				expectedPayment.setSettleCurrency("CNY");
				expectedPayment.setSettleRate("1");
				expectedPayment.setRealForeignAmount(needPayAmount);
				expectedPayment.setShenqiPaymentRmbAmount(payReq.getPayAmount());
			}
		}
		
		expectedPayment.setGatewayPayType(payReq.getPayType());
		
		// 如果是买家同意线下支付的订单，不需要验证paymentDb
		if (null == payReq.getPayType() || !payReq.getPayType().equalsIgnoreCase("200"))
			verifyPaymentDb(expectedPayment, paymentPo);

		BigDecimal[] weights = new BigDecimal[orderList.size()];

		for (int i = 0; i < orderList.size(); i++) {
			weights[i] = realNeedPayAmountList[i];
		}

		if (type == PayTypeEnum.FULL_BALANCE) {
			// 当全余额支付时，计算余额支付按比例分摊到每个订单上的金额
			BigDecimal accountPaid[] = Utils.apportionByWeights3(
					useAccountAmount, weights, null);

			for (int i = 0; i < orderList.size(); i++) {

				// 订单号
				long orderId = orderList.get(i).getOrderId();

				Logger.comment("校验订单：" + orderId);

				// 订单表(order)
				OrderPo ymtOrders = database.selectOrderbyOrderId(orderId);

				Logger.comment("验证订单号:" + orderId);

				Logger.comment("验证订单表(order)表");

				if (payReq.getTradeType() == 1) {

					// 如果是安利会员订单
					if (TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders
							.getOrderType())) {

						Thread.sleep(15000);
						Logger.verifyEquals(4, ymtOrders.getOrderStatus(),
								"验证orderStatus");
					} else if (!payReq.getPayType().equalsIgnoreCase("200"))
						Logger.verifyEquals(2, ymtOrders.getOrderStatus(),
								"验证orderStatus");
					else
						Logger.verifyEquals(1, ymtOrders.getOrderStatus(),
								"验证orderStatus");
					
					if (!payReq.getPayType().equalsIgnoreCase("200")) {
						
						Logger.verifyEquals(paymentId, ymtOrders.getPaymentId(),
								"验证数据库PaymentId");
						DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
								ymtOrders.getThirdpartyPaidAmount(),
								"验证数据库ThirdpartyPaidAmount");
					} else {
						Logger.verifyEquals(null, ymtOrders.getPaymentId(),
								"验证数据库PaymentId");
						DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
								ymtOrders.getThirdpartyPaidAmount(),
								"验证数据库ThirdpartyPaidAmount");
					}
					
					DataUtil.verifyDecimalEquals(accountPaid[i],
							ymtOrders.getAccountPaidAmount(),
							"验证数据库AccountPaidAmount");
					
					if (null != payment_payCurrency && isShenqiOrder) {
						
						BigDecimal[] result = Utils.apportionByWeights3(
								payReq.getPayAmount(), realNeedPayAmountList,
								null);

						DataUtil.verifyDecimalEquals(result[i],
								ymtOrders.getShenqiPaymentRmbAmount(),
								"验证order表ShenqiPaymentRmbAmount");
						Logger.verifyEquals(
								ymtOrders
										.getShenqiPaymentRmbAmount()
										.divide(realNeedPayAmountList[i], 5,
												BigDecimal.ROUND_HALF_DOWN)
										.toPlainString(),
								ymtOrders.getExchangeRate(),
								"验证order表ExchangeRate");
					}
					
					if (!TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders
							.getOrderType())) {

						List<Settlement> anliSettlements = settlementWrapper
								.selectByOrderIdAndUserId(orderId, userId);

						if (anliSettlements.size() > 0) {

							Logger.verifyEquals(anliSettlements.get(0)
									.getSettlement_amount(), ymtOrders
									.getOrderOwnerRebateAmount(),
									"OrderOwnerRebateAmount");
							Logger.verifyEquals(true,
									ymtOrders.isActualRebate(),
									"验证isActualRebate");
						} else {
							Logger.verifyEquals(null,
									ymtOrders.getOrderOwnerRebateAmount(),
									"OrderOwnerRebateAmount");
							Logger.verifyEquals(false,
									ymtOrders.isActualRebate(),
									"验证isActualRebate");
						}
					} else {

						Logger.verifyEquals(null,
								ymtOrders.getOrderOwnerRebateAmount(),
								"OrderOwnerRebateAmount");
						if (this.isExistsLinkPayAnliOrder(ymtOrders))
							Logger.verifyEquals(true,
									ymtOrders.isActualRebate(),
									"验证isActualRebate");
						else
							Logger.verifyEquals(false, ymtOrders.isActualRebate(),
									"验证isActualRebate");
					}
					
					if (payReq.getPayType().equalsIgnoreCase("200"))
						Logger.verifyEquals(true, ymtOrders.getOfflinePayFlag(), "OfflinePayFlag");
					else
						Logger.verifyEquals(false, ymtOrders.getOfflinePayFlag(), "OfflinePayFlag");
					
				} else {
					Logger.verifyEquals(1, ymtOrders.getOrderStatus(),
							"验证orderStatus");
					Logger.verifyEquals(paymentId,
							ymtOrders.getEarnestPaymentId(), "验证数据库PaymentId");
					DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
							ymtOrders.getEarnestThirdpartyPaidAmount(),
							"验证数据库earnestThirdpartyPaidAmount");

					DataUtil.verifyDecimalEquals(accountPaid[i],
							ymtOrders.getEarnestAccountPaidAmount(),
							"验证数据库earnestAccountPaidAmount");
					Logger.verifyEquals(true, Utils.calcTimeSpanMin(ymtOrders
							.getEarnestPaidTime()) < 2,
							"验证数据库AddTime跟系统当前时间差为2分钟内");
				}

				DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
						ymtOrders.getThirdpartyDiscount(),
						"验证数据库ThirdpartyDiscount");

				if (payReq.getTradeType() == 2
						&& ymtOrders.getEarnestPaymentId() != null)
					Logger.verifyEquals(true, ymtOrders.getCanConfirm(),
							"验证数据库CanConfirm");
				else
					Logger.verifyEquals(false, ymtOrders.getCanConfirm(),
							"验证数据库CanConfirm");

				if (ReduceStatusEnum.SUCCESS.getCode() == cardStatus) {
					DataUtil.verifyDecimalEquals(
							orderList
									.get(i)
									.getOrderPo()
									.getTotalPrice()
									.add(orderList.get(i).getOrderPo()
											.getFreight())
									.subtract(accountPaid[i]),
							ymtOrders.getCardAmount(), "验证数据库CardAmount");
				}

				// 有app内平台立减时，校验折扣金额的分摊
				if (Utils.isBiggerThan(payDeductAmount, BigDecimal.ZERO)) {
					BigDecimal ymtPromotionAmount[] = Utils
							.apportionByWeights3(payDeductAmount, weights, null);

					DataUtil.verifyDecimalEquals(ymtPromotionAmount[i],
							ymtOrders.getYmtPromotionAmount(),
							"验证数据库ymtPromotionAmount");

					List<OrderDetailPo> orderDetailPoList = database
							.selectOrderDetailbyOrderId(orderId);

					BigDecimal[] orderDetailWeights = orderDetailPoList
							.stream()
							.map(e -> e.getProductPrice().multiply(
									new BigDecimal(e.getProductCount())))
							.collect(Collectors.toList())
							.toArray(new BigDecimal[0]);

					BigDecimal[] orderDetailYmtPromotionAmount = Utils
							.apportionByWeights3(ymtPromotionAmount[i],
									orderDetailWeights, null);

					for (int j = 0; j < orderDetailPoList.size(); j++) {
						OrderDetailPo orderDetailPo = orderDetailPoList.get(j);

						Logger.comment(String.format(
								"验证订单商品表(order_detail) 上第 %s 商品	平台立减优惠金额",
								j + 1));

						DataUtil.verifyDecimalEquals(
								orderDetailYmtPromotionAmount[j],
								orderDetailPo.getYmtPromotionAmount(),
								"商品上第三方支付优惠金额");
					}
				}

				// 订单主状态操作日志表(order_status_log)
				OrderStatusLogPo orderStatusLogPo = database
						.selectOrderStatusLogByOrderId(orderId);
				
				Logger.comment("验证订单主状态操作日志表(order_status_log)");

				if (payReq.getTradeType() == 1) {

					if (TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders.getOrderType())) {

						Logger.verifyEquals("确认收货", orderStatusLogPo.getMemo(),
								"验证数据库Memo");
						Logger.verifyEquals(4,
								orderStatusLogPo.getOrderStatus(),
								"验证数据库OrderStatus");
						Logger.verifyEquals(-1L, orderStatusLogPo.getOperator(),
								"验证数据库Operator");
					} else {

						Logger.verifyEquals("支付完成", orderStatusLogPo.getMemo(),
								"验证数据库Memo");
						Logger.verifyEquals(2,
								orderStatusLogPo.getOrderStatus(),
								"验证数据库OrderStatus");
						Logger.verifyEquals(userId, orderStatusLogPo.getOperator(),
								"验证数据库Operator");
					}
				} else {
					Logger.verifyEquals("定金已付，待支付全款",
							orderStatusLogPo.getMemo(), "验证数据库Memo");
					Logger.verifyEquals(1, orderStatusLogPo.getOrderStatus(),
							"验证数据库OrderStatus");
				}

				Logger.verifyEquals(
						true,
						Utils.calcTimeSpanMin(orderStatusLogPo.getAddTime()) < 2,
						"验证数据库AddTime跟系统当前时间差为2分钟内");

				Logger.verifyEquals(orderId, orderStatusLogPo.getOrderId(),
						"验证数据库OrderId");
			}
		} else {

			BigDecimal thirdPaid[];

			if (useAccountAmount == BigDecimal.ZERO
					&& cmbDiscountAmount == BigDecimal.ZERO
					&& payDeductAmount == BigDecimal.ZERO)
				thirdPaid = weights;
			else
				thirdPaid = Utils.apportionByWeights3(
						needPayAmount.subtract(useAccountAmount).subtract(
								cmbDiscountAmount), weights, null);

			BigDecimal thirdDiscount[] = Utils.apportionByWeights3(
					cmbDiscountAmount, weights, null);

			for (int i = 0; i < orderList.size(); i++) {

				// 订单号
				long orderId = orderList.get(i).getOrderId();

				// 订单表(order)
				OrderPo ymtOrders = database.selectOrderbyOrderId(orderId);

				// 订单应付金额
				BigDecimal orderPayAmount = ymtOrders.getPayableAmount();

				Logger.comment("验证订单号:" + orderId);

				Logger.comment("验证订单表(order)表");

				if (payReq.getTradeType() == 1) {

					// 如果是安利会员订单
					if (TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders.getOrderType())) {
						
						Thread.sleep(15000);
						Logger.verifyEquals(4, ymtOrders.getOrderStatus(),
								"验证orderStatus");
					}
					else if (!payReq.getPayType().equalsIgnoreCase("200"))
						Logger.verifyEquals(2, ymtOrders.getOrderStatus(),
								"验证orderStatus");
					else
						Logger.verifyEquals(1, ymtOrders.getOrderStatus(),
								"验证orderStatus");

					if (!payReq.getPayType().equalsIgnoreCase("200"))
						Logger.verifyEquals(paymentId, ymtOrders.getPaymentId(),
								"验证数据库PaymentId");
					else
						Logger.verifyEquals(null, ymtOrders.getPaymentId(),
								"验证数据库PaymentId");

					if (needPayAmount.compareTo(realNeedPayAmount) != 0) {

						if (!payReq.getPayType().equalsIgnoreCase("200"))
							DataUtil.verifyDecimalEquals(
									thirdPaid[i],
									ymtOrders.getThirdpartyPaidAmount(),
									"验证数据库ThirdpartyPaidAmount");
						else
							DataUtil.verifyDecimalEquals(
									BigDecimal.ZERO,
									ymtOrders.getThirdpartyPaidAmount(),
									"验证数据库ThirdpartyPaidAmount");

						DataUtil.verifyDecimalEquals(
								orderPayAmount.subtract(thirdPaid[i])
										.subtract(thirdDiscount[i]),
								ymtOrders.getAccountPaidAmount(),
								"验证数据库AccountPaidAmount");

						DataUtil.verifyDecimalEquals(
								needPayAmount.add(orderDiscount),
								realNeedPayAmount, "验证数据库realNeedPayAmount");
					} else {

						if (!payReq.getPayType().equalsIgnoreCase("200"))
							DataUtil.verifyDecimalEquals(
									thirdPaid[i],
									ymtOrders.getThirdpartyPaidAmount(),
									"验证数据库ThirdpartyPaidAmount");
						else
							DataUtil.verifyDecimalEquals(
									BigDecimal.ZERO,
									ymtOrders.getThirdpartyPaidAmount(),
									"验证数据库ThirdpartyPaidAmount");

						DataUtil.verifyDecimalEquals(
								orderPayAmount.subtract(thirdPaid[i]).subtract(
										thirdDiscount[i]),
								ymtOrders.getAccountPaidAmount(),
								"验证数据库AccountPaidAmount");
					}
					
					if (null != payment_payCurrency && isShenqiOrder) {
						
						BigDecimal[] result = Utils.apportionByWeights3(
								payReq.getPayAmount(), realNeedPayAmountList,
								null);

						DataUtil.verifyDecimalEquals(result[i],
								ymtOrders.getShenqiPaymentRmbAmount(),
								"验证order表ShenqiPaymentRmbAmount");
						Logger.verifyEquals(
								ymtOrders
										.getShenqiPaymentRmbAmount()
										.divide(realNeedPayAmountList[i], 5,
												BigDecimal.ROUND_HALF_DOWN)
										.toPlainString(),
								ymtOrders.getExchangeRate(),
								"验证order表ExchangeRate");
					}
					
					if (!TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders
							.getOrderType())) {

						List<Settlement> anliSettlements = settlementWrapper
								.selectByOrderIdAndUserId(orderId, userId);

						if (anliSettlements.size() > 0) {

							Logger.verifyEquals(anliSettlements.get(0)
									.getSettlement_amount(), ymtOrders
									.getOrderOwnerRebateAmount(),
									"OrderOwnerRebateAmount");
							Logger.verifyEquals(
									true,
									ymtOrders.isActualRebate(), "验证isActualRebate");
						} else {
							Logger.verifyEquals(null,
									ymtOrders.getOrderOwnerRebateAmount(),
									"OrderOwnerRebateAmount");
							Logger.verifyEquals(
									false,
									ymtOrders.isActualRebate(), "验证isActualRebate");
						}
					} else {
						
						Logger.verifyEquals(null,
								ymtOrders.getOrderOwnerRebateAmount(),
								"OrderOwnerRebateAmount");
						
						if (this.isExistsLinkPayAnliOrder(ymtOrders))
							Logger.verifyEquals(
									true,
									ymtOrders.isActualRebate(), "验证isActualRebate");
						else
							Logger.verifyEquals(
									false,
									ymtOrders.isActualRebate(), "验证isActualRebate");
					}
					
					if (payReq.getPayType().equalsIgnoreCase("200"))
						Logger.verifyEquals(true, ymtOrders.getOfflinePayFlag(), "OfflinePayFlag");
					else
						Logger.verifyEquals(false, ymtOrders.getOfflinePayFlag(), "OfflinePayFlag");
					
				} else {
					
					Logger.verifyEquals(1, ymtOrders.getOrderStatus(),
							"验证orderStatus");
					
					if (null == payReq.getPayType() || !payReq.getPayType().equalsIgnoreCase("200")) {
						
						Logger.verifyEquals(paymentId,
								ymtOrders.getEarnestPaymentId(), "验证数据库PaymentId");
						DataUtil.verifyDecimalEquals(thirdPaid[i],
								ymtOrders.getEarnestThirdpartyPaidAmount(),
								"验证数据库ThirdpartyPaidAmount");
					} else {
						
						Logger.verifyEquals(null,
								ymtOrders.getEarnestPaymentId(), "验证数据库PaymentId");
						DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
								ymtOrders.getEarnestThirdpartyPaidAmount(),
								"验证数据库ThirdpartyPaidAmount");
					}

					DataUtil.verifyDecimalEquals(
							orderPayAmount.subtract(thirdPaid[i]).subtract(
									thirdDiscount[i]),
							ymtOrders.getEarnestAccountPaidAmount(),
							"验证数据库AccountPaidAmount");
					Logger.verifyEquals(true, Utils.calcTimeSpanMin(ymtOrders
							.getEarnestPaidTime()) < 2,
							"验证数据库AddTime跟系统当前时间差为2分钟内");
				}

				DataUtil.verifyDecimalEquals(thirdDiscount[i],
						ymtOrders.getThirdpartyDiscount(),
						"验证数据库ThirdpartyDiscount");

				// 有app内平台立减时，校验折扣金额的分摊
				if (Utils.isBiggerThan(payDeductAmount, BigDecimal.ZERO)) {
					BigDecimal ymtPromotionAmount[] = Utils
							.apportionByWeights3(payDeductAmount, weights, null);

					DataUtil.verifyDecimalEquals(ymtPromotionAmount[i],
							ymtOrders.getYmtPromotionAmount(),
							"验证数据库ymtPromotionAmount");

					List<OrderDetailPo> orderDetailPoList = database
							.selectOrderDetailbyOrderId(orderId);

					BigDecimal[] orderDetailWeights = orderDetailPoList
							.stream()
							.map(e -> e.getProductPrice().multiply(
									new BigDecimal(e.getProductCount())))
							.collect(Collectors.toList())
							.toArray(new BigDecimal[0]);

					BigDecimal[] orderDetailYmtPromotionAmount = Utils
							.apportionByWeights3(ymtPromotionAmount[i],
									orderDetailWeights, null);

					for (int j = 0; j < orderDetailPoList.size(); j++) {
						OrderDetailPo orderDetailPo = orderDetailPoList.get(j);

						Logger.comment(String.format(
								"验证订单商品表(order_detail) 上第 %s 商品	平台立减优惠金额",
								j + 1));

						DataUtil.verifyDecimalEquals(
								orderDetailYmtPromotionAmount[j],
								orderDetailPo.getYmtPromotionAmount(),
								"商品上第三方支付优惠金额");
					}
				}

				// 有招行折扣的才校验订单商品表 折扣金额的分摊
				if (Utils.isBiggerThan(cmbDiscountAmount, BigDecimal.ZERO)) {

					// 订单商品表(order_detail)
					List<OrderDetailPo> orderDetailPoList = database
							.selectOrderDetailbyOrderId(orderId);

					BigDecimal[] orderDetailWeights = orderDetailPoList
							.stream()
							.map(e -> e.getProductPrice().multiply(
									new BigDecimal(e.getProductCount())))
							.collect(Collectors.toList())
							.toArray(new BigDecimal[0]);

					BigDecimal[] orderDetailDiscount = Utils
							.apportionByWeights3(thirdDiscount[i],
									orderDetailWeights, null);

					for (int j = 0; j < orderDetailPoList.size(); j++) {

						OrderDetailPo orderDetailPo = orderDetailPoList.get(j);

						Logger.comment(String.format(
								"验证订单商品表(order_detail) 上第 %s 商品	第三方支付优惠金额",
								j + 1));

						DataUtil.verifyDecimalEquals(orderDetailDiscount[j],
								orderDetailPo.getThirdpartyDiscount(),
								"商品上第三方支付优惠金额");

						// 订单组合子商品表（order_detail_sub）
						List<OrderDetailSubPo> orderDetailSubPoList = database
								.selectOrderDetailSubByDetailId(orderDetailPo
										.getOrderDetailId());

						if (!CollectionUtils.isEmpty(orderDetailSubPoList)) {

							BigDecimal[] orderDetailSubWeights = orderDetailSubPoList
									.stream()
									.map(e -> e
											.getOriginalPrice()
											.multiply(
													new BigDecimal(e
															.getProductCount())))
									.collect(Collectors.toList())
									.toArray(new BigDecimal[0]);

							BigDecimal[] orderDetailSubDiscount = Utils
									.apportionByWeights3(
											orderDetailDiscount[j],
											orderDetailSubWeights, null);

							for (int k = 0; k < orderDetailSubPoList.size(); k++) {

								OrderDetailSubPo orderDetailSubPo = orderDetailSubPoList
										.get(k);

								Logger.comment(String
										.format("验证订单组合子商品表（order_detail_sub） 上第 %s 套装商品优惠金额",
												k + 1));

								DataUtil.verifyDecimalEquals(
										orderDetailSubDiscount[k],
										orderDetailSubPo
												.getThirdpartyDiscount(),
										"套装商品上第三方支付优惠金额");
							}
						}
					}
				}
				
				if (null == payReq.getPayType() || !payReq.getPayType().equalsIgnoreCase("200")) {
				
					// 订单主状态操作日志表(order_status_log)
					OrderStatusLogPo orderStatusLogPo = database
							.selectOrderStatusLogByOrderId(orderId);

					Logger.comment("验证订单主状态操作日志表(order_status_log)");

					if (payReq.getTradeType() == 1) {

						if (TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders.getOrderType())) {

							Logger.verifyEquals("确认收货", orderStatusLogPo.getMemo(),
									"验证数据库Memo");
							Logger.verifyEquals(4,
									orderStatusLogPo.getOrderStatus(),
									"验证数据库OrderStatus");
							Logger.verifyEquals(-1L, orderStatusLogPo.getOperator(),
									"验证数据库Operator");
						} else {

							Logger.verifyEquals("支付完成", orderStatusLogPo.getMemo(),
									"验证数据库Memo");
							Logger.verifyEquals(2,
									orderStatusLogPo.getOrderStatus(),
									"验证数据库OrderStatus");
							Logger.verifyEquals(userId,
									orderStatusLogPo.getOperator(), "验证数据库Operator");
						}
					} else {
						Logger.verifyEquals("定金已付，待支付全款",
								orderStatusLogPo.getMemo(), "验证数据库Memo");
						Logger.verifyEquals(1, orderStatusLogPo.getOrderStatus(),
								"验证数据库OrderStatus");
					}

					Logger.verifyEquals(
							true,
							Utils.calcTimeSpanMin(orderStatusLogPo.getAddTime()) < 2,
							"验证数据库AddTime跟系统当前时间差为2分钟内");

					Logger.verifyEquals(orderId, orderStatusLogPo.getOrderId(),
							"验证数据库OrderId");
				}
			}
		}
	}

	/**
	 * 支付表(payment)
	 * 
	 * @param expectedPayment
	 * @param actualPayment
	 * @throws Exception 
	 */
	private void verifyPaymentDb(PaymentPo expectedPayment,
			PaymentPo actualPayment) throws Exception {

		Logger.comment(String.format("验证支付表(payment) ,paymentId :%s",
				expectedPayment.getPaymentId()));

		DataUtil.verifyDecimalEquals(expectedPayment.getThirdpartyAmount(),
				actualPayment.getThirdpartyAmount(), "验证数据库ThirdpartyAmount");
		DataUtil.verifyDecimalEquals(expectedPayment.getRealPaidAmount(),
				actualPayment.getRealPaidAmount(), "验证数据库RealPaidAmount");
		/*
		 * Logger.verifyEquals(expectedPayment.getGatewayPaymentId(),
		 * actualPayment.getGatewayPaymentId(), "验证数据库GatewayPaymentId");
		 * 
		 * Logger.verifyEquals(expectedPayment.getThirdpartyPaymentId(),
		 * actualPayment.getThirdpartyPaymentId(), "验证数据库ThirdpartyPaymentId");
		 * Logger.verifyEquals(expectedPayment.getGatewayCallback(),
		 * actualPayment.getGatewayCallback(), "验证数据库GatewayCallback");
		 * 
		 * Logger.verifyEquals(expectedPayment.getGatewayCallbackTime(),
		 * actualPayment.getGatewayCallbackTime(), "验证数据库GatewayCallbackTime");
		 * 
		 * Logger.verifyEquals(expectedPayment.getPayChannel(),
		 * actualPayment.getPayChannel(), "验证数据库PayChannel");
		 */

		Logger.verifyEquals(expectedPayment.getTradeType(),
				actualPayment.getTradeType(), "验证数据库TradeType");
		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualPayment.getUpdateTime()) < 2,
				"验证数据库UpdateTime跟系统当前时间差为2分钟内");
		Logger.verifyEquals(true,
				Utils.calcTimeSpanMin(actualPayment.getAddTime()) < 2,
				"验证数据库AddTime跟系统当前时间差为2分钟内");

		DataUtil.verifyDecimalEquals(expectedPayment.getPayableAmount(),
				actualPayment.getPayableAmount(), "验证数据库PayableAmount");
		Logger.verifyEquals(expectedPayment.getPaymentId(),
				actualPayment.getPaymentId(), "验证数据库PaymentId");
		Logger.verifyEquals(expectedPayment.getUserId(),
				actualPayment.getUserId(), "验证数据库UserId");
		DataUtil.verifyDecimalEquals(expectedPayment.getThirdpartyDiscount(),
				actualPayment.getThirdpartyDiscount(),
				"验证数据库ThirdpartyDiscount");

		DataUtil.verifyDecimalEquals(expectedPayment.getPayDeductAmount(),
				actualPayment.getPayDeductAmount(), "验证数据库payDeductAmount");

		Logger.verifyEquals(expectedPayment.getPayStatus(),
				actualPayment.getPayStatus(), "验证数据库PayStatus");

		Logger.verifyEquals(expectedPayment.getRetryTimes(),
				actualPayment.getRetryTimes(), "验证数据库RetryTimes");

		DataUtil.verifyDecimalEquals(expectedPayment.getAccountAmount(),
				actualPayment.getAccountAmount(), "验证数据库AccountAmount");
		Logger.verifyEquals(expectedPayment.getPayType(),
				actualPayment.getPayType(), "验证数据库PayType");

		Logger.verifyEquals(expectedPayment.getMemo(), actualPayment.getMemo(),
				"验证数据库Memo");

		Logger.verifyEquals(expectedPayment.getSettleCurrency(),
				actualPayment.getSettleCurrency(), "验证数据库SettleCurrency");
		Logger.verifyEquals(expectedPayment.getSettleRate(),
				actualPayment.getSettleRate(), "验证数据库SettleRate");
		Logger.verifyEquals(expectedPayment.getForeignAmount(),
				actualPayment.getForeignAmount(), "验证数据库ForeignAmount");
		if (null == payReq.getPayType())
			Logger.verifyEquals(null, actualPayment.getRealForeignAmount(),
					"验证数据库RealForeignAmount");
		else if (payReq.getPayType().equalsIgnoreCase("6000")
				|| payReq.getPayType().equalsIgnoreCase("6010")
				|| payReq.getPayType().equalsIgnoreCase("6011")
				|| payReq.getPayType().equalsIgnoreCase("6006"))
			Logger.verifyEquals(
					Utils.zeroIfNull(expectedPayment.getRealForeignAmount())
							.setScale(2, BigDecimal.ROUND_HALF_DOWN),
					actualPayment.getRealForeignAmount(),
					"验证数据库RealForeignAmount");
		else
			Logger.verifyEquals(null, actualPayment.getRealForeignAmount(),
					"验证数据库RealForeignAmount");
		
		Logger.verifyEquals(expectedPayment.getPayCurrency(),
				actualPayment.getPayCurrency(), "验证数据库PayCurrency");
		Logger.verifyEquals(expectedPayment.getExchangeRate(),
				actualPayment.getExchangeRate(), "验证数据库ExchangeRate");
		Logger.verifyEquals(expectedPayment.getShenqiPaymentRmbAmount(),
				actualPayment.getShenqiPaymentRmbAmount(), "验证数据库ShenqiPaymentRmbAmount");
		Logger.verifyEquals(expectedPayment.getAppName(),
				actualPayment.getAppName(), "验证数据库appName");
		Logger.verifyEquals(expectedPayment.getGatewayPayType(),
				actualPayment.getGatewayPayType(), "验证数据库gatewayPayType");
		
		Logger.verifyEquals(expectedPayment.getPaidMerchantNum(),
				actualPayment.getPaidMerchantNum(), "验证数据库paidMerchantNum");
		
		if (expectedPayment.getThirdpartyAmount().compareTo(BigDecimal.ZERO) > 0)
			DataUtil.verifyDecimalEquals(
					expectedPayment.getThirdpartyAmount(),
					new BigDecimal(TradingCallService
							.queryByTradingId(expectedPayment.getPaymentId()
									.toString())), "验证第三方扣减金额");
	}

	/**
	 * 验证alipay app 返回
	 * 
	 * @param orderId
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	private void verifyAlipayApp(List<OrderPo> orderList) throws Exception {

		// 第三方支付的金额=订单应付金额-使用余额支付的金额
		BigDecimal totalFee = orderList.stream()
				.map(orderPo -> orderPo.getPayableAmount())
				.reduce(BigDecimal.ZERO, BigDecimal::add)
				.subtract(Utils.zeroIfNull(payReq.getUseAccountAmount()));

		for (OrderPo order : orderList) {

			Logger.comment(String.format("验证订单 : %s 支付宝 APP Result报文",
					order.getOrderId()));

			Thread.sleep(15000);

			String productName = String.format("%s的订单", new OrderWapper()
					.selectOrderExtByOrderId(order.getOrderId())
					.getUserLoginId());

			Map m = (Map) FormatUtil.GSONToObject(payReqCall.getData()
					.optString("result"), Map.class);

			Logger.verifyNotNull(m.get("Sign"), "验证Sign非空");
			// Logger.verifyEquals(PayGateWayCallService.Alipay_MERID,
			// m.get("Partner"), "验证partner合作者身份ID");
			Logger.verifyEquals("2088701734809577", m.get("Partner"),
					"验证partner合作者身份ID");
			// Logger.verifyEquals(PayGateWayCallService.Alipay_EMAIL,
			// m.get("SellerId"), "验证SellerId买家支付宝账号");
			Logger.verifyEquals("ap.ymt@ymatou.com", m.get("SellerId"),
					"验证SellerId买家支付宝账号");

			// 新支付网关 收单表
			MPayment mpayment = new PayGateWayWapper()
					.selectPaymentByTradingid(
							payReqCall.getData().optString("tradingId")).get(0);

			// HashMap mext = (HashMap) FormatUtil.GSONToObject(
			// payReq.getParamExt(), HashMap.class);

			boolean isHangzhouBonded = database
					.selectOrderDetailbyOrderId(order.getOrderId()).get(0)
					.getBondedArea() == BondedAreaEnum.HangZhou.getCode();

			String trandno = mpayment.getPaymentId();

			Logger.verifyEquals(trandno, m.get("OutTradeNo"), "验证OutTradeNo");

			Logger.verifyEquals(
					true,
					m.get("Subject").equals(
							String.format("%s的订单", order.getUserId()))
							|| m.get("Subject").equals(productName),
					"验证Subject");

			Logger.comment("totalFee:" + totalFee.toString());

			DataUtil.verifyDecimalEquals(new BigDecimal(m.get("TotalFee")
					.toString()), totalFee, "验证TotalFee:" + m.get("TotalFee"));

			if (EnvSetup.getEnv().equals("sit1")) {
				// Logger.verifyEquals(
				// "http://" + "sit"
				// + ".payment.ymatou.com:8380/notify/10"
				// + payReq.getPayType(), m.get("NotifyUrl"),
				// "验证NotifyUrl");
				Logger.verifyEquals(
						"http://sit.payment.ymatou.com:8380/notify/13",
						m.get("NotifyUrl"), "验证NotifyUrl");
			} else if (EnvSetup.getEnv().equals("uat")) {
				Logger.verifyEquals(
						"http://" + "uat"
								+ ".payment.ymatou.com:8480/notify/10"
								+ payReq.getPayType(), m.get("NotifyUrl"),
						"验证NotifyUrl");
			}
			Logger.verifyEquals("mobile.securitypay.pay", m.get("Service"),
					"验证Service");
			Logger.verifyEquals("1", m.get("PaymentType"), "验证PaymentType");
			Logger.verifyEquals("utf-8", m.get("InputCharset"),
					"验证InputCharset");
			Logger.verifyEquals("10d", m.get("ItBPay"), "验证ItBPay");
			Logger.verifyEquals("RSA", m.get("SignType"), "验证SignType");
			Logger.verifyEquals(true, m.get("QuerySuccess"), "验证QuerySuccess");
			Logger.verifyEquals("成功", m.get("Message"), "验证Message");
			Logger.comment("验证EncryptStr");
			Map mencrypt = FormatUtil.httpStringToMap(m.get("EncryptStr")
					.toString());
			Logger.verifyNotNull(mencrypt.get("sign"), "验证Sign非空");
			// Logger.verifyEquals(PayGateWayCallService.Alipay_MERID,
			// mencrypt.get("partner"), "验证partner合作者身份ID");
			// Logger.verifyEquals(PayGateWayCallService.Alipay_EMAIL,
			// mencrypt.get("seller_id"), "验证seller_id买家支付宝账号");
			Logger.verifyEquals("2088701734809577", mencrypt.get("partner"),
					"验证partner合作者身份ID");
			Logger.verifyEquals("ap.ymt@ymatou.com", mencrypt.get("seller_id"),
					"验证seller_id买家支付宝账号");
			Logger.verifyEquals(trandno, mencrypt.get("out_trade_no"),
					"验证out_trade_no");

			/*
			 * Logger.verifyEquals(productName, mencrypt.get("subject"),
			 * "验证subject");
			 */

			Logger.verifyEquals(true, TestDataManager.equalsBigDecimal(
					new BigDecimal(mencrypt.get("total_fee").toString()),
					totalFee.toString()),
					"验证total_fee:" + mencrypt.get("total_fee"));
			if (EnvSetup.getEnv().equals("sit1")) {
				// Logger.verifyEquals(
				// "http://" + "sit"
				// + ".payment.ymatou.com:8380/notify/10"
				// + payReq.getPayType(),
				// mencrypt.get("notify_url"), "验证notify_url");
				Logger.verifyEquals(
						"http://sit.payment.ymatou.com:8380/notify/13",
						mencrypt.get("notify_url"), "验证notify_url");
			} else if (EnvSetup.getEnv().equals("uat")) {
				Logger.verifyEquals(
						"http://" + "uat"
								+ ".payment.ymatou.com:8480/notify/10"
								+ payReq.getPayType(),
						mencrypt.get("notify_url"), "验证notify_url");
			}
			Logger.verifyEquals("mobile.securitypay.pay",
					mencrypt.get("service"), "验证service");
			Logger.verifyEquals("1", mencrypt.get("payment_type"),
					"验证payment_type");
			Logger.verifyEquals("utf-8", mencrypt.get("_input_charset"),
					"验证_input_charset");
			Logger.verifyEquals("10d", mencrypt.get("it_b_pay"), "验证it_b_pay");
			Logger.verifyEquals("RSA", mencrypt.get("sign_type"), "验证sign_type");
			Logger.verifyEquals("m.alipay.com", mencrypt.get("show_url"),
					"验证show_url");

			// 杭保实名,非杭保不验
			if (isHangzhouBonded) {
				Logger.verifyEquals("T", mencrypt.get("rn_check"), "验证rn_check");

			}

			Logger.verifyNotNull(mencrypt.get("sign"), "验证sign非空");
		}

	}

	/**
	 * 校验Html Form返回 支付宝PC支付
	 * 
	 * @param orderId
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void verifyHtmlResult(List<OrderPo> orderList) throws Exception {

		// 第三方支付的金额=订单应付金额-使用余额支付的金额
		BigDecimal totalFee = orderList.stream()
				.map(orderPo -> orderPo.getPayableAmount())
				.reduce(BigDecimal.ZERO, BigDecimal::add)
				.subtract(Utils.zeroIfNull(payReq.getUseAccountAmount()));
		for (OrderPo order : orderList) {

			Logger.comment(String.format("验证 订单 : %s 支付宝PC Result报文",
					order.getOrderId()));

			Map m = new HashMap<String, String>();

			Thread.sleep(15000);
			String productName = String.format("%s的订单", new OrderWapper()
					.selectOrderExtByOrderId(order.getOrderId())
					.getUserLoginId());

			// 返回报文result
			String result = payReqCall.getData().getString("result");
			List<String> namelist = TestDataManager.getRegexList(result,
					"(?<=name=\").*?(?=\")");
			List<String> valuelist = TestDataManager.getRegexList(result,
					"(?<=value=\").*?(?=\")");
			if (valuelist.size() == namelist.size()) {
				for (int i = 0; i < namelist.size(); i++) {
					m.put(namelist.get(i), valuelist.get(i));
				}
			} else {
				throw new Exception("verifyResult失败,结果集name value 不匹配");
			}

			// 新支付网关 收单表
			MPayment mpayment = new PayGateWayWapper()
					.selectPaymentByTradingid(
							payReqCall.getData().optString("tradingId")).get(0);

			// HashMap mext = (HashMap) FormatUtil.GSONToObject(
			// payReq.getParamExt(), HashMap.class);

			boolean isHangzhouBonded = database
					.selectOrderDetailbyOrderId(order.getOrderId()).get(0)
					.getBondedArea() == BondedAreaEnum.HangZhou.getCode();

			String trandno = mpayment.getPaymentId();

			Logger.verifyEquals(
					true,
					m.get("subject").equals(
							String.format("%s的订单", order.getUserId()))
							|| m.get("subject").equals(productName),
					"验证Subject");

			Logger.verifyEquals("RSA", m.get("sign_type"), "验证sign_type");

			if (EnvSetup.getEnv().equals("sit1")) {
				Logger.verifyEquals(
						"http://" + "sit" + ".payment.ymatou.com:8380/notify/"
								+ payReq.getPayType(), m.get("notify_url"),
						"验证notify_url");
				Logger.verifyEquals(trandno, m.get("out_trade_no"),
						"验证out_trade_no");

				Logger.verifyEquals(
						"http://" + "sit"
								+ ".payment.ymatou.com:8380/callback/"
								+ payReq.getPayType(), m.get("return_url"),
						"验证return_url");

			} else if (EnvSetup.getEnv().equals("uat")) {
				Logger.verifyEquals(
						"http://" + "uat"
								+ ".payment.ymatou.com:8480/notify/10"
								+ payReq.getPayType(), m.get("notify_url"),
						"验证notify_url");
				Logger.verifyEquals(trandno, m.get("out_trade_no"),
						"验证out_trade_no");
				Logger.verifyEquals(
						"http://" + "uat"
								+ ".payment.ymatou.com:8480/callback/10"
								+ payReq.getPayType(), m.get("return_url"),
						"验证return_url");
			}

			// sign算法未知
			Logger.verifyNotNull(m.get("sign"), "验证sign非空");
			Logger.verifyEquals("utf-8", m.get("_input_charset"),
					"验证_input_charset");
			Logger.verifyEquals(payReq.getUserIp(), m.get("exter_invoke_ip"),
					"验证exter_invoke_ip");

			DataUtil.verifyDecimalEquals(new BigDecimal(m.get("total_fee")
					.toString()), totalFee, "验证total_fee:" + m.get("total_fee"));

			if (isHangzhouBonded) {
				Logger.comment("验证杭保信息");
				Logger.verifyEquals(
						"{&quot;needBuyerRealnamed&quot;:&quot;T&quot;}",
						m.get("buyer_info"), "验证buyer_info买家信息");
				Logger.verifyEquals("alipay.acquire.page.createandpay",
						m.get("service"), "验证service统一下单并支付");
				Logger.verifyEquals("FAST_INSTANT_TRADE_PAY",
						m.get("product_code"), "验证product_code订单业务类型");
			} else {
				Logger.comment("验证非杭保信息");

				Logger.verifyEquals("create_direct_pay_by_user",
						m.get("service"), "验证service统一下单并支付");

				Logger.verifyEquals("N", m.get("default_login"),
						"验证default_login默认登录");
			}
			// 固定
			Logger.verifyEquals("2088701734809577", m.get("partner"),
					"验证partner合作者身份ID");
			Logger.verifyNotNull(m.get("anti_phishing_key"),
					"验证anti_phishing_key防钓鱼时间戳");
			Logger.verifyEquals("ap.ymt@ymatou.com", m.get("seller_email"),
					"验证seller_email买家支付宝账号");
			Logger.verifyEquals("1", m.get("payment_type"),
					"验证payment_type 1（商品购买）");
		}
	}

	/**
	 * 校验weixin 微信-JSAPI
	 * 
	 * @param orderId
	 * @throws Exception
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private void verifyWeixin() {
		try {
			Logger.comment("验证微信JSAPI Result报文");
			HashMap mresult = (HashMap) FormatUtil.GSONToObject(payReqCall
					.getData().getString("result"), HashMap.class);
			Logger.verifyNotNull(mresult.get("AppID"), "验证AppID 公众号");
			Logger.verifyNotNull(mresult.get("TimeStamp"), "验证TimeStamp非空");
			Logger.verifyNotNull(mresult.get("NonceStr"), "验证NonceStr非空");
			Logger.verifyNotNull(mresult.get("Package"), "验证Package非空");
			// String sign = null;
			// String mysign = null;
			if (payReq.getPayType().equals("15")) {
				Logger.verifyEquals("Sign=WXPay", mresult.get("Package"),
						"验证SignType");

				// sign = mresult.get("Sign").toString();

				// String merchantId = mresult.get("MerchantId").toString();
				Map resetmap = new TreeMap();
				resetmap.put("appid", mresult.get("AppID"));
				resetmap.put("partnerid", mresult.get("MerchantId"));
				resetmap.put("prepayid", mresult.get("PayToken"));
				resetmap.put("timestamp", mresult.get("TimeStamp"));
				resetmap.put("package", mresult.get("Package"));
				resetmap.put("noncestr", mresult.get("NonceStr"));
				Logger.debug("15 resetmap:" + resetmap);

				// String src = FormatUtil.mapToHttpString(resetmap, false);

				// mysign = new Sign().SignSHA1WithRSA(src);

				// mysign = new Sign().signMd5(resetmap, Sign.weixinAppKey);

			} else if (payReq.getPayType().equals("14")) {
				Logger.verifyEquals("MD5", mresult.get("SignType"),
						"验证SignType");

				// sign = mresult.get("Sign").toString();

				Map resetmap = new TreeMap();
				resetmap.put("appId", mresult.get("AppID"));
				resetmap.put("timeStamp", mresult.get("TimeStamp"));
				resetmap.put("package", mresult.get("Package"));
				resetmap.put("nonceStr", mresult.get("NonceStr"));
				resetmap.put("signType", mresult.get("SignType"));
				Logger.debug("14 resetmap:" + resetmap);

				// mysign = new Sign().signMd5(resetmap, Sign.weixinJSAPIKey);
			}
			/*
			 * Logger.verifyEquals(mysign.toLowerCase(), sign.toLowerCase(),
			 * "验证Sign");
			 */
		} catch (Exception e) {
		}
	}
	
	public Boolean isExistsLinkPayAnliOrder(OrderPo orderPo) {
		
		Long linkPayAnliOrderId = orderPo.getLinkPayAnliOrderId();
		
		if (null != linkPayAnliOrderId)
			return true;
		else
			return false;
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_001() {
		Logger.start(true, "通过余额支付订单,成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.TEN,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(price);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(price,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_002() {
		Logger.start(true, "订单支付价格为0.01.通过余额支付成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			PlaceOrderReq placeOrderReq = TradingCallService
					.buildStandPlaceOrderReq();
			
			OrderGroupVo orderGroupVo = TradingCallService.createOrderGroupVo(sellerId, sellerName);
			OrderVo orderVo = TradingCallService.createOrderVo();
			
			// 创建一个普通商品
			TradingProductVo product = TradingProductVo.createPro(sellerId,
					sellerName, 100);
			
			OrderItemVo orderItemVo = TradingCallService.createOrderItemVo(
					product.getProductId(), product.getCatalogId());
			
			orderItemVo.setProductPrice(new BigDecimal("0.01"));
			orderItemVo.setProductNum(1);
			
			orderVo.setOrderItems(Arrays.asList(orderItemVo));
			orderGroupVo.setOrders(Arrays.asList(orderVo));
			placeOrderReq.setOrderGroups(Arrays.asList(orderGroupVo));

			TradingServiceResp placeOrderResp = TradingCallService
					.callPlaceOrderService(placeOrderReq);

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(price);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(price,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_003() {
		Logger.start(true, "通过余额支付,userid为null订单,成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			// Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			// BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
			// userId.intValue(), 1);

			// 参数
			// payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(price);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals("400", payReqCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_004() {
		Logger.start(true, "一笔交易里有多个订单,通过余额支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 获取用户需要支付的金额
			BigDecimal payAmount = placeOrderResp.getPayableAmount();

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(payAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			// 数据库校验
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(payAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_005() {
		Logger.start(true, "使用支付宝app第三方支付,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			DataUtil.verifyDecimalEquals(
					order.getPayableAmount(),
					new BigDecimal(payReqCall.getData().optString(
							"thirdPartyAmount")), "验证thirdPartyAmount");

			// 验证支付网关返回报文
			verifyAlipayApp(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_006() {
		Logger.start(true, "使用支付宝pc第三方支付,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();
			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("Form", payReqCall.getData().get("resultType"),
					"验证Code");

			// 验证支付网关返回报文
			verifyHtmlResult(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_007() {
		Logger.start(true, "使用支付宝wap第三方支付,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("11");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			// 验证支付网关返回报文
			Logger.verifyEquals(
					true,
					payReqCall
							.getData()
							.get("result")
							.toString()
							.contains(
									"http://wappaygw.alipay.com/service/rest.htm"),
					"验证Code");
			Logger.verifyEquals("Query",
					payReqCall.getData().get("resultType"), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_008() {
		Logger.start(true, "使用支付宝app第三方支付,userid为0,支付失败");
		try {
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(0);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(2222);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.ERROR400, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("100", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("userId:userId未提供", payReqCall.getMsg(),
					"验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_009() {
		Logger.start(true, "使用微信-JSAPI第三方支付,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("14");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			// 验证支付网关返回报文
			// Logger.verifyEquals(true,
			// payReqCall.getData().get("result").toString().contains("http://wappaygw.alipay.com/service/rest.htm"),
			// "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getString("resultType")
					.toString(), "验证ResultType");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_010() {
		Logger.start(true, "使用微信app第三方支付,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			// 验证支付网关返回报文
			Logger.verifyEquals("JSON",
					payReqCall.getData().getString("resultType").toString(),
					"验证ResultType");
			verifyWeixin();

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_011() {
		Logger.start(true, "使用支付宝app第三方支付,订单物流为杭保,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder2("张三",
					LogisticsTypeEnum.BondedDelivery, false);

			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// 验证支付网关返回报文
			verifyAlipayApp(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_012() {
		Logger.start(true, "杭保物流下单,使用支付宝app第三方支付,验证第三方支付接口返回报文");
		try {

			TradingServiceResp placeOrderResp = placeOrder2("张三",
					LogisticsTypeEnum.BondedDelivery, false);

			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// 验证支付网关返回报文
			verifyAlipayApp(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_013() {
		Logger.start(true, "使用账户余额+第三方混合支付,验证第三方支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 订单应付金额
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// 使用余额支付一部分
			payReq.setUseAccountAmount(totalPrice.subtract(new BigDecimal(11)));
			payReq.setTradingId(tradingId);
			payReq.setTradingPwd("abc123");
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// 验证支付网关返回报文
			verifyAlipayApp(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_014() {
		Logger.start(true, "使用支付宝支付,可选为支付方式(70:宝付),验证宝付支付接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setTerminalSource(TerminalSourceEnum.Android);
			payReq.setOptionalPayTypes(Arrays.asList(70));
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			;

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_015() {
		Logger.start(true, "使用支付宝支付,可选为支付方式为空,验证接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setTerminalSource(TerminalSourceEnum.Android);
			// payReq.setOptionalPayTypes(Arrays.asList(70));
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证resultType");
			// 验证支付网关返回报文
			verifyAlipayApp(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_016() {
		Logger.start(true, "使用支付宝支付,可选为支付方式为不存在的类型,验证接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			OrderPo order = placeOrderResp.getOrderList().get(0).getOrderPo();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setTerminalSource(TerminalSourceEnum.Android);
			payReq.setOptionalPayTypes(Arrays.asList(71));
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证resultType");
			// 验证支付网关返回报文
			verifyAlipayApp(Arrays.asList(order));

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_017() {
		Logger.start(true, "使用微信支付,可选为支付方式为宝付(70),验证接口返回报文");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setTerminalSource(TerminalSourceEnum.Android);
			payReq.setOptionalPayTypes(Arrays.asList(70));
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证resultType");
			// 验证支付网关返回报文
			verifyWeixin();

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_018() {
		Logger.start(true, "同一个主单下的订单,根据 orderIds 组合支付成功,模拟支付网关回调成功.");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(true);

			List<Order> orderList = placeOrderResp.getOrderList();

			List<Long> orderIds = new ArrayList<Long>();

			orderList.forEach(o -> orderIds.add(o.getOrderId()));

			Long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = new BigDecimal(30);

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setOrderIds(orderIds);

			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// AccountCallServiceV2.getAccountentrylist(userId.intValue());

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_019() {
		Logger.start(true, "不是一个主单下的多个订单,根据 orderIds 组合支付成功,模拟支付网关回调成功.");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(true);

			TradingServiceResp placeOrderResp2 = placeOrder4(true);

			Order order1 = placeOrderResp.getOrderList().get(0);

			Order order2 = placeOrderResp2.getOrderList().get(0);

			List<Long> orderIds = new ArrayList<Long>();

			orderIds.add(order1.getOrderId());
			orderIds.add(order2.getOrderId());

			Long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = order1.getOrderPo().getPayableAmount()
					.add(order2.getOrderPo().getPayableAmount());

			BigDecimal useAccountAmount = new BigDecimal(30);

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setOrderIds(orderIds);

			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// AccountCallServiceV2.getAccountentrylist(userId.intValue());

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					Lists.newArrayList(order1, order2), BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_020() {
		Logger.start(true, "一个订单多个商品,使用余额+第三方组合支付,模拟支付网关回调成功.");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(true);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = new BigDecimal(30);

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("90");
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// AccountCallServiceV2.getAccountentrylist(userId.intValue());

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_021() {
		Logger.start(true, "一个订单多个商品,支付宝支付,模拟支付网关回调成功.");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(true);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// AccountCallServiceV2.getAccountentrylist(userId.intValue());

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_022() {
		Logger.start(true, "一个订单多个商品,微信支付,模拟支付网关回调成功.");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(true);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			// AccountCallServiceV2.getAccountentrylist(userId.intValue());

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_023() {
		Logger.start(true, "一个订单多个商品,全额使用招行支付,支付网关回调成功,校验招行平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(true);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("50");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal cmbDiscountAmount = new BigDecimal(
					new Random().nextInt(10)).add(BigDecimal.ONE);

			// 支付网关支付回调交易
			PayGateWayCallService.cmbNotifyCall(String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), cmbDiscountAmount.toString());

			Thread.sleep(10000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			// 验证
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, cmbDiscountAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_024() {
		Logger.start(true, "一个订单多个商品,使用招行+用户余额,支付网关回调成功,校验招行平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(true);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("50");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal cmbDiscountAmount = new BigDecimal(
					new Random().nextInt(10)).add(BigDecimal.ONE);

			// 支付网关支付回调交易
			PayGateWayCallService.cmbNotifyCall(String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), cmbDiscountAmount.toString());

			Thread.sleep(10000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			// 验证
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, cmbDiscountAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_025() {
		Logger.start(true, "含有组合商品的订单,全额使用招行支付,支付网关回调成功,校验招行平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder();

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 获取用户需要支付的金额
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("50");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal cmbDiscountAmount = new BigDecimal(
					new Random().nextInt(10)).add(BigDecimal.ONE);

			// 支付网关支付回调交易
			PayGateWayCallService.cmbNotifyCall(String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), cmbDiscountAmount.toString());

			Thread.sleep(10000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			// 验证
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, cmbDiscountAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_026() {
		Logger.start(true, "一笔交易多个订单,所有子订单自动取消,支付网关回调,走快速退款,原路退回到第三方账户");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			// 取消所有子单
			orderList.forEach(o -> TradingCallService.cancelOrder(
					o.getOrderId(), CancelOrderTypeEnum.BUYER_CANCEL_ORDER,
					userId));

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(2000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			PayGateWayCallService.refundNotifyCall("13",
					String.valueOf(thirdTradingId), userId.intValue());

			Thread.sleep(3000);

			// 用户退款资金详情表（user_refund_fund_detail）
			UserRefundFundDetailPo userRefundFundDetailPo = database
					.selectUserRefundFundDetailByPaymentId(Long
							.valueOf(thirdTradingId));

			UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

			expectUserRefundFundDetailPo.setPaymentId(Long
					.valueOf(thirdTradingId));
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setBizType(3);
			expectUserRefundFundDetailPo.setThirdpartyAmount(totalPrice
					.subtract(useAccountAmount));
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
			expectUserRefundFundDetailPo.setRetryTimes(0);
			expectUserRefundFundDetailPo.setMemo("0");
			expectUserRefundFundDetailPo.setAccountAmount(BigDecimal.ZERO);

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_027() {
		Logger.start(true, "一笔交易多个订单,子订单部分取消,支付网关回调,已取消订单退款原路退回");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			// 取消部分子单
			List<Order> cancelList = orderList.subList(0, 2);

			cancelList.forEach(o -> TradingCallService.cancelOrder(
					o.getOrderId(), CancelOrderTypeEnum.BUYER_CANCEL_ORDER,
					userId));

			// 支付的订单列表
			List<Order> paidlList = orderList.subList(2, orderList.size());

			BigDecimal paidAmount = orderList.stream()
					.map(o -> o.getOrderPo().getPayableAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			BigDecimal[] weights = new BigDecimal[orderList.size()];

			for (int i = 0; i < orderList.size(); i++) {
				weights[i] = orderList.get(i).getOrderPo().getPayableAmount();
			}

			if (!Utils.isBiggerThanOrEqual(paidAmount, useAccountAmount)) {
				paidAmount = useAccountAmount;
			}

			// 计算第三方支付按比例分摊到每个订单上的金额
			BigDecimal thirdPaid[] = Utils.apportionByWeights3(
					paidAmount.subtract(useAccountAmount), weights, null);

			int i = 0;

			for (Order order : paidlList) {

				long orderId = order.getOrderId();

				OrderPo ymtOrders = database
						.selectOrderbyOrderId(orderId);

				Logger.comment(String.format("验证订单表(order)表 orderId: %s",
						orderId));

				// 如果是安利会员订单
				if (TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders.getOrderType())) {
					
					Thread.sleep(15000);
					Logger.verifyEquals(4, ymtOrders.getOrderStatus(),
							"验证orderStatus");
				} else if (!payReq.getPayType().equalsIgnoreCase("200"))
					Logger.verifyEquals(2, ymtOrders.getOrderStatus(),
							"验证orderStatus");
				else
					Logger.verifyEquals(1, ymtOrders.getOrderStatus(),
							"验证orderStatus");

				Logger.verifyEquals(thirdTradingId, ymtOrders.getPaymentId(),
						"验证数据库PaymentId");

				DataUtil.verifyDecimalEquals(thirdPaid[i + 2],
						ymtOrders.getThirdpartyPaidAmount(),
						"验证数据库ThirdpartyPaidAmount");

				DataUtil.verifyDecimalEquals(ymtOrders.getPayableAmount()
						.subtract(thirdPaid[i + 2]), ymtOrders
						.getAccountPaidAmount(), "验证数据库AccountPaidAmount");

				i++;
			}

			// 用户退款资金详情表（user_refund_fund_detail）
			List<UserRefundFundDetailPo> userRefundFundDetailList = database
					.selectUserRefundFundDetailListByPaymentId(Long
							.valueOf(thirdTradingId));

			int n = 0;
			for (UserRefundFundDetailPo userRefundFundDetailPo : userRefundFundDetailList) {

				UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

				expectUserRefundFundDetailPo.setOrderId(cancelList.get(n)
						.getOrderId());
				expectUserRefundFundDetailPo.setPaymentId(Long
						.valueOf(thirdTradingId));
				expectUserRefundFundDetailPo.setAccountRefundStatus(4);
				expectUserRefundFundDetailPo.setBizType(4);
				expectUserRefundFundDetailPo.setThirdpartyAmount(thirdPaid[n]);
				expectUserRefundFundDetailPo.setThirdpartyRefundStatus(3);
				expectUserRefundFundDetailPo.setRetryTimes(0);
				expectUserRefundFundDetailPo.setMemo("0");
				expectUserRefundFundDetailPo.setAccountAmount(cancelList.get(n)
						.getOrderPayableAmount().subtract(thirdPaid[n]));

				RefundService.verifyUserRefundFundDetailDb(
						expectUserRefundFundDetailPo, userRefundFundDetailPo);
				n++;
			}

			BigDecimal refundAccountPaidAmount = userRefundFundDetailList
					.stream().map(o -> o.getAccountAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(
					refundAccountPaidAmount.subtract(useAccountAmount),
					afterAmount.subtract(beforeAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	// 宝付渠道下线了
	public void Tc_OrderPay_028() {
		Logger.start(true, "使用宝付支付,模拟网关支付通知回调,验证宝付支付接口返回报文");
		try {

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(price1);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setTerminalSource(TerminalSourceEnum.Android);
			payReq.setOptionalPayTypes(Arrays.asList(70));
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			Logger.comment("第三方支付回调");

			PayGateWayCallService.notifyCall("70", thirdTradingId.toString(),
					totalPrice.subtract(BigDecimal.ZERO).toString(),
					userId.intValue());

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("BaofooToken",
					payReqCall.getData().get("resultType"), "验证resultType");

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}

	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_029() {
		Logger.start(true, "使用账户余额+第三方混合支付,第三方支付回调前,重复用余额支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 订单应付金额
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 全款第三方支付
			// 13 为 app国际支付宝,15 微信
			String payType = "13";
			BigDecimal useAccountAmount = new BigDecimal(11);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// 使用余额支付一部分
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			payReq.setTradingPwd("abc123");
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			Long thirdTradingId = payReqCall.getTradingId();

			// 重复用余额支付
			TradingCallService.payOrder(userId, totalPrice, tradingId, payType);

			// 支付网关支付回调交易
			Logger.comment("第三方支付回调");

			PayGateWayCallService.notifyCall(payType,
					thirdTradingId.toString(),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(totalPrice,
					beforeAmount.subtract(afterAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_030() {
		Logger.start(true, "使用账户余额+第三方混合支付,第三方支付回调前,重复第三方支付,网关成功回调第一笔第三方支付");
		try {

			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 13 为 app国际支付宝,15 微信
			String payType = "15";
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// 使用余额支付一部分
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			payReq.setTradingPwd("abc123");
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			Long thirdTradingId = payReqCall.getData().getLong("tradingId");

			// 第二次支付用的余额
			BigDecimal useAccountAmount2 = BigDecimal.ZERO;

			Logger.comment("第三方支付回调前,用第三方重复支付");
			// 重复混合支付支付
			Long thirdTradingId2 = TradingCallService.payOrder(userId,
					useAccountAmount2, tradingId, payType);
			
			// 支付前账户金额，由于payOrder会给账户充值，获取支付前余额需要放在这里
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 支付网关支付回调第一笔支付
			PayGateWayCallService.notifyCall("13", thirdTradingId.toString(),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(4000);

			// 支付网关支付回调第二笔支付
			PayGateWayCallService.notifyCall(payType,
					thirdTradingId2.toString(),
					totalPrice.subtract(useAccountAmount2).toString(),
					userId.intValue());

			Thread.sleep(3000);

			verifyDb(thirdTradingId, useAccountAmount, orderList,
					BigDecimal.ZERO);

			PayGateWayCallService.refundNotifyCall(payType,
					String.valueOf(thirdTradingId2), userId.intValue());

			Thread.sleep(4000);

			// 用户退款资金详情表（user_refund_fund_detail）
			UserRefundFundDetailPo userRefundFundDetailPo = database
					.selectUserRefundFundDetailByPaymentId(thirdTradingId2);

			UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

			expectUserRefundFundDetailPo.setPaymentId(thirdTradingId2);
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setBizType(3);
			expectUserRefundFundDetailPo.setThirdpartyAmount(totalPrice
					.subtract(useAccountAmount2));
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
			expectUserRefundFundDetailPo.setRetryTimes(0);
			expectUserRefundFundDetailPo.setMemo("0");
			expectUserRefundFundDetailPo.setAccountAmount(BigDecimal.ZERO);

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_031() {
		Logger.start(true, "第三方支付回调前,重复第三方支付,网关成功回调第二笔第三方支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 13 为 app国际支付宝,15 微信
			String payType = "15";
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// 使用余额支付一部分
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			payReq.setTradingPwd("abc123");
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			Long thirdTradingId = payReqCall.getData().getLong("tradingId");

			// 第二次支付用的余额
			BigDecimal useAccountAmount2 = BigDecimal.ZERO;

			Logger.comment("第三方支付回调前,用第三方重复支付");
			// 重复混合支付支付
			Long thirdTradingId2 = TradingCallService.payOrder(userId,
					useAccountAmount2, tradingId, payType);

			// 支付前账户金额，由于payOrder会给账户充值，获取支付前余额需要放在这里
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 支付网关支付回调第二笔支付
			PayGateWayCallService.notifyCall(payType,
					thirdTradingId2.toString(),
					totalPrice.subtract(useAccountAmount2).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付网关支付回调第一笔支付
			PayGateWayCallService.notifyCall("13", thirdTradingId.toString(),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(4000);

			verifyDb(thirdTradingId2, useAccountAmount2, orderList,
					BigDecimal.ZERO);

			PayGateWayCallService.refundNotifyCall("13",
					String.valueOf(thirdTradingId), userId.intValue());

			Thread.sleep(4000);

			// 用户退款资金详情表（user_refund_fund_detail）
			UserRefundFundDetailPo userRefundFundDetailPo = database
					.selectUserRefundFundDetailByPaymentId(Long
							.valueOf(thirdTradingId));

			UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

			expectUserRefundFundDetailPo.setPaymentId(Long
					.valueOf(thirdTradingId));
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setBizType(3);
			expectUserRefundFundDetailPo.setThirdpartyAmount(totalPrice
					.subtract(useAccountAmount));
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
			expectUserRefundFundDetailPo.setRetryTimes(0);
			expectUserRefundFundDetailPo.setMemo("0");
			expectUserRefundFundDetailPo.setAccountAmount(BigDecimal.ZERO);

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount2,
					beforeAmount.subtract(afterAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_032() {
		Logger.start(true, "订单支付成功,校验发送风控校验");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 获取用户需要支付的金额
			BigDecimal payAmount = placeOrderResp.getPayableAmount();

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(payAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_033() {
		Logger.start(true, "订单收件人,收件人在年度额度身份证黑名单里,贝海保税商品支付后,直接取消订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			String recvName = IdCardService.Idcard_Black_User;

			TradingServiceResp placeOrderResp = IdCardService.placeOrder(
					recvName, LogisticsTypeEnum.BondedDelivery, false,
					new BigDecimal(102));

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();// 支付金额

			Logger.comment("前置数据准备结束");

			IdCardService.updateIdcardBlackList(userId, recvName);

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Thread.sleep(30000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			Ts_CancelOrder.verifyOrderStatus(18, orderId, -1L,
					CancelOrderTypeEnum.EXCEEDLIMIT_CANCEL_ORDER,
					"收件人额度超过2万金额取消订单");

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(afterAmount, beforeAmount,
					"校验用户账户余额退款成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_OrderPay_034() {
		Logger.start(true, "订单收件人,年消费额度超过20000,贝海保税商品支付后,直接取消订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			String recvName = IdCardService.Idcard_Cost_User;

			TradingServiceResp placeOrderResp = IdCardService.placeOrder(
					recvName, LogisticsTypeEnum.BondedDelivery, false,
					new BigDecimal(102));

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();// 支付金额

			Logger.comment("前置数据准备结束");

			IdCardService.updateIdcardCost(userId, recvName, new BigDecimal(
					20000));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Thread.sleep(30000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			Ts_CancelOrder.verifyOrderStatus(18, orderId, -1L,
					CancelOrderTypeEnum.EXCEEDLIMIT_CANCEL_ORDER,
					"收件人额度超过2万金额取消订单");

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(afterAmount, beforeAmount,
					"校验用户账户余额退款成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_035() {
		Logger.start(true, "订单收件人,年消费额度不超过20000,贝海保税商品正常支付,不会取消订单");
		try {

			// 创建订单
			Logger.comment("前置数据准备");
			String recvName = IdCardService.Idcard_Cost_User;

			TradingServiceResp placeOrderResp = IdCardService.placeOrder(
					recvName, LogisticsTypeEnum.BondedDelivery, false,
					new BigDecimal(102));

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();// 支付金额

			Logger.comment("前置数据准备结束");

			IdCardService.updateIdcardCost(userId, recvName,
					new BigDecimal(200));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_036() {
		Logger.start(true, "订单收件人,年消费额度超过20000,非贝海保税商品正常支付,不会取消订单");
		try {

			// 创建订单
			Logger.comment("前置数据准备");
			String recvName = IdCardService.Idcard_Cost_User;

			TradingServiceResp placeOrderResp = IdCardService.placeOrder(
					recvName, LogisticsTypeEnum.BondedDelivery, false,
					new BigDecimal(102));

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal useAccountAmount = placeOrderResp.getPayableAmount();// 支付金额

			Logger.comment("前置数据准备结束");

			IdCardService.updateIdcardCost(userId, recvName, new BigDecimal(
					20000));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P2.class)
	@TestCase
	public void Tc_OrderPay_037() {
		Logger.start(false, "支付密码错误,支付失败");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(BigDecimal.TEN);
			payReq.setTradingId(tradingId);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			String tradingPassword = "123a";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("{\"paymethod\":A, \"showmode\":B}");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.FAILED201, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals(true,
					payReqCall.getMsg().contains(ECode.FAILED201_MSG_39),
					"验证Msg" + payReqCall.getMsg());
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_038() {
		Logger.start(false, "tradingPwd,orderIds 都为null 支付失败");
		try {

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(3383L);
			payReq.setUseAccountAmount(BigDecimal.TEN);
			// payReq.setTradingId();
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("{\"paymethod\":A, \"showmode\":B}");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.ERROR400, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("100", payReqCall.getBCode(), "验证bcode");

			Logger.verifyEquals("交易号或订单号未提供", payReqCall.getMsg(), "验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_039() {
		Logger.start(false, "userid为空,支付失败");
		try {

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			// payReq.setUserId(3383L);
			payReq.setUseAccountAmount(BigDecimal.TEN);
			payReq.setTradingId(111111111);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("{\"paymethod\":A, \"showmode\":B}");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.ERROR400, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("100", payReqCall.getBCode(), "验证bcode");

			Logger.verifyEquals("userId:userId未提供", payReqCall.getMsg(),
					"验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_040() {
		Logger.start(false, "输入来源ip为空,支付失败");
		try {

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(3383L);
			payReq.setUseAccountAmount(BigDecimal.TEN);
			payReq.setTradingId(9923434L);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.ERROR400, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("100", payReqCall.getBCode(), "验证bcode");

			Logger.verifyEquals("userIp:userIp未提供!", payReqCall.getMsg(),
					"验证Msg");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_041() {
		Logger.start(false, "输入支付方式为空,支付失败");
		try {

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(3383L);
			payReq.setUseAccountAmount(BigDecimal.TEN);
			payReq.setTradingId(1343243L);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("");

			payReq.setParamExt("{\"paymethod\":A, \"showmode\":B}");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			Logger.verifyEquals(ECode.ERROR400, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("100", payReqCall.getBCode(), "验证bcode");

			Logger.verifyEquals("payType:支付方式不能为空!", payReqCall.getMsg(),
					"验证Msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_042() {
		Logger.start(false, "用户可用余额为0,使用账户余额账户");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			// 订单应付金额
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 重置用户余额为0
			AccountCallServiceV2.resetAccount(
					AccountCallServiceV2.getAccountId(userId.intValue()),
					BigDecimal.ZERO, BigDecimal.TEN);

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(totalPrice);
			payReq.setTradingId(tradingId);
			payReq.setTradingPwd("abc123");
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals("201", payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("105", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("账户金额不足", payReqCall.getMsg(), "验证Msg");

			// 恢复用户余额
			AccountCallServiceV2.resetAccount(
					AccountCallServiceV2.getAccountId(userId.intValue()),
					new BigDecimal(1000000), BigDecimal.TEN);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_043() {
		Logger.start(false, "用户可用余额小于订单支付金额,使用账户余额账户");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService.placeOrderWithCoupon();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 订单应付金额
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			String accountid = AccountCallServiceV2.getAccountId(userId
					.intValue());

			// 重置用户账户可用余额小于 支付金额
			AccountCallServiceV2.resetAccount(accountid,
					totalPrice.subtract(BigDecimal.ONE), BigDecimal.ZERO);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(totalPrice);
			payReq.setTradingId(tradingId);
			payReq.setTradingPwd("abc123");
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals("201", payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("105", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("账户金额不足", payReqCall.getMsg(), "验证Msg");
			// 恢复用户余额
			AccountCallServiceV2.resetAccount(accountid,
					new BigDecimal(100000), BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_044() {
		Logger.start(false, "此交易号不存在,支付失败");
		try {

			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(3383);
			payReq.setUseAccountAmount(BigDecimal.TEN);
			payReq.setTradingId(1234561232);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals("201", payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("101", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("待支付订单不存在", payReqCall.getMsg(), "验证Msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P3.class)
	@TestCase
	public void Tc_OrderPay_045() {
		Logger.start(false, "当前订单状态不能支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingCallService
					.cancelOrderBeforePaid(CancelOrderTypeEnum.BUYER_CANCEL_ORDER);

			long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");
			// 参数
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(new BigDecimal(10));
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);

			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals("201", payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("102", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("订单状态不匹配，请确认后重新付款", payReqCall.getMsg(),
					"验证Msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_046() {
		Logger.start(true, "orderIds 里有重复的订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(true);

			Order order1 = placeOrderResp.getOrderList().get(0);

			List<Long> orderIds = new ArrayList<Long>();

			orderIds.add(order1.getOrderId());
			orderIds.add(order1.getOrderId());

			Long userId = placeOrderResp.getUserId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = order1.getOrderPo().getPayableAmount()
					.add(order1.getOrderPo().getPayableAmount());

			BigDecimal useAccountAmount = totalPrice;

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setOrderIds(orderIds);

			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals("201", payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("105", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("存在重复订单号，请确认后重新付款", payReqCall.getMsg(),
					"验证Msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_048() {
		Logger.start(true, "使用预付卡的订单,使用余额支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(false);

			long tradingId = placeOrderResp.getTradingId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 获取用户需要支付的订单总金额
			BigDecimal totalPrice = TradingCallService
					.getPayableAmount(tradingId);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(totalPrice);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(price,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_049() {
		Logger.start(true, "使用预付卡的订单,使用余额+第三方组合支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			BigDecimal useAccountAmount = new BigDecimal(20);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");

			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_050() {
		Logger.start(true, "app内立减支付金额,使用余额支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.TEN,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			long tradingId = placeOrderResp.getTradingId();
			Long userId = placeOrderResp.getUserId();

			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			
			MainOrderPo actualMainOrder = database
					.selectMianOrderbyId(tradingId);
			BigDecimal payDeductAmount = actualMainOrder.getPayDeductAmount();

			// 获取用户需要支付的金额,允许使用app内立减支付，需要减去payDeductAmount
			BigDecimal totalPrice = TradingCallService.getPayableAmount(
					tradingId).subtract(payDeductAmount);
			price = price.subtract(payDeductAmount);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(totalPrice);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setCanPayDeduct(true);

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(price,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_051() {
		Logger.start(true, "app内立减支付金额,使用余额+第三方支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.TEN,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			BigDecimal useAccountAmount = new BigDecimal(20);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");

			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setCanPayDeduct(true);

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();
			
			MainOrderPo actualMainOrder = database.selectMianOrderbyId(payReq
					.getTradingId());
			BigDecimal payDeductAmount = actualMainOrder.getPayDeductAmount();

			// 支付网关支付回调交易,可以使用app内立减优惠，需要再减去paydeductAmount
			PayGateWayCallService.notifyCall(
					"13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount)
							.subtract(payDeductAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_052() {
		Logger.start(true, "一笔交易多个订单app内立减支付金额,子订单全部取消,支付网关回调,已取消订单原路退回");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.TEN,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setCanPayDeduct(true);
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();
			
			MainOrderPo actualMainOrder = database.selectMianOrderbyId(payReq
					.getTradingId());
			BigDecimal payDeductAmount = actualMainOrder.getPayDeductAmount();

			// 取消所有子单
			orderList.forEach(o -> TradingCallService.cancelOrder(
					o.getOrderId(), CancelOrderTypeEnum.BUYER_CANCEL_ORDER,
					userId));

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall(
					"13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount)
							.subtract(payDeductAmount).toString(),
					userId.intValue());

			Thread.sleep(2000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			PayGateWayCallService.refundNotifyCall("13",
					String.valueOf(thirdTradingId), userId.intValue());

			Thread.sleep(3000);

			// 用户退款资金详情表（user_refund_fund_detail）
			UserRefundFundDetailPo userRefundFundDetailPo = database
					.selectUserRefundFundDetailByPaymentId(Long
							.valueOf(thirdTradingId));

			UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

			expectUserRefundFundDetailPo.setPaymentId(Long
					.valueOf(thirdTradingId));
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setBizType(3);
			expectUserRefundFundDetailPo.setThirdpartyAmount(totalPrice
					.subtract(useAccountAmount).subtract(payDeductAmount));
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
			expectUserRefundFundDetailPo.setRetryTimes(0);
			// expectUserRefundFundDetailPo.setMemo("0");

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_053() {
		Logger.start(true, "一笔交易多个订单含app内支付立减,子订单部分取消,支付网关回调,已取消订单退款原路退回");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder4(false, true);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");
			payReq.setCanPayDeduct(true);

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			// 支付的订单列表
			List<Order> paidlList = orderList.subList(2, orderList.size());
			
			MainOrderPo actualMainOrder = database.selectMianOrderbyId(payReq
					.getTradingId());
			BigDecimal payDeductAmount = actualMainOrder.getPayDeductAmount();

			// 取消部分子单
			List<Order> cancelList = orderList.subList(0, 2);

			cancelList.forEach(o -> TradingCallService.cancelOrder(
					o.getOrderId(), CancelOrderTypeEnum.BUYER_CANCEL_ORDER,
					userId));

			// 使用app内立减支付时需要减去payDeductAmount
			BigDecimal paidAmount = orderList.stream()
					.map(o -> o.getOrderPo().getPayableAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add)
					.subtract(payDeductAmount);

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall(
					"13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount)
							.subtract(payDeductAmount).toString(),
					userId.intValue());

			Thread.sleep(15000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("JSON", payReqCall.getData().get("resultType"),
					"验证Code");

			BigDecimal[] weights = new BigDecimal[orderList.size()];

			for (int i = orderList.size() - 1; i >= 0; i--) {
				weights[i] = orderList.get(i).getOrderPo().getPayableAmount();
			}

			if (!Utils.isBiggerThanOrEqual(paidAmount, useAccountAmount)) {
				paidAmount = useAccountAmount;
			}

			// 计算第三方支付按比例分摊到每个订单上的金额
			BigDecimal thirdPaid[] = Utils.apportionByWeights3(
					paidAmount.subtract(useAccountAmount), weights, null);

			// 有app内平台立减时，校验折扣金额的分摊
			if (Utils.isBiggerThan(payDeductAmount, BigDecimal.ZERO)) {

				BigDecimal ymtPromotionAmount[] = Utils.apportionByWeights3(
						payDeductAmount, weights, null);
				int i = 0;

				for (Order order : orderList) {

					long orderId = order.getOrderId();
					OrderPo ymtOrders = database
							.selectOrderbyOrderId(orderId);

					DataUtil.verifyDecimalEquals(ymtPromotionAmount[i],
							ymtOrders.getYmtPromotionAmount(),
							"验证数据库ymtPromotionAmount");

					i++;
				}
			}

			int i = 0;

			for (Order order : paidlList) {

				long orderId = order.getOrderId();
				OrderPo ymtOrders = database
						.selectOrderbyOrderId(orderId);

				Logger.comment(String.format("验证订单表(order)表 orderId: %s",
						orderId));

				// 如果是安利会员订单
				if (TradingPlaceAnliOrderCallService.isAnliMember(ymtOrders.getOrderType())) {
					
					Thread.sleep(15000);
					Logger.verifyEquals(4, ymtOrders.getOrderStatus(),
							"验证orderStatus");
				}
				else
					Logger.verifyEquals(2, ymtOrders.getOrderStatus(),
							"验证orderStatus");

				if (!payReq.getPayType().equalsIgnoreCase("200"))
					Logger.verifyEquals(thirdTradingId, ymtOrders.getPaymentId(),
							"验证数据库PaymentId");
				else
					Logger.verifyEquals(null, ymtOrders.getPaymentId(),
							"验证数据库PaymentId");

				DataUtil.verifyDecimalEquals(thirdPaid[i + 2],
						ymtOrders.getThirdpartyPaidAmount(),
						"验证数据库ThirdpartyPaidAmount");

				DataUtil.verifyDecimalEquals(ymtOrders.getPayableAmount()
						.subtract(thirdPaid[i + 2]), ymtOrders
						.getAccountPaidAmount(), "验证数据库AccountPaidAmount");

				i++;
			}

			// 用户退款资金详情表（user_refund_fund_detail）
			List<UserRefundFundDetailPo> userRefundFundDetailList = database
					.selectUserRefundFundDetailListByPaymentId(Long
							.valueOf(thirdTradingId));

			int n = 0;
			for (UserRefundFundDetailPo userRefundFundDetailPo : userRefundFundDetailList) {

				UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

				expectUserRefundFundDetailPo.setPaymentId(Long
						.valueOf(thirdTradingId));
				expectUserRefundFundDetailPo.setAccountRefundStatus(4);
				expectUserRefundFundDetailPo.setBizType(4);
				expectUserRefundFundDetailPo.setThirdpartyAmount(thirdPaid[n]);
				expectUserRefundFundDetailPo.setThirdpartyRefundStatus(3);
				expectUserRefundFundDetailPo.setRetryTimes(0);

				RefundService.verifyUserRefundFundDetailDb(
						expectUserRefundFundDetailPo, userRefundFundDetailPo);
				n++;
			}

			BigDecimal refundAccountPaidAmount = userRefundFundDetailList
					.stream().map(o -> o.getAccountAmount())
					.reduce(BigDecimal.ZERO, BigDecimal::add);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 因为使用了app内立减支付，优惠金额并不会退回原账户
			DataUtil.verifyDecimalEquals(
					refundAccountPaidAmount.subtract(useAccountAmount),
					afterAmount.subtract(beforeAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_054() {
		Logger.start(true, "app内立减支付金额,使用第三方支付宝支付");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false, BigDecimal.TEN,
							userId, LogisticsTypeEnum.OVERSEAS_DELIVERY);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			BigDecimal useAccountAmount = BigDecimal.TEN;

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");

			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			payReq.setCanPayDeduct(true);

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();
			
			MainOrderPo actualMainOrder = database.selectMianOrderbyId(payReq
					.getTradingId());
			BigDecimal payDeductAmount = actualMainOrder.getPayDeductAmount();

			// 支付网关支付回调交易,可以使用app内立减优惠，需要再减去paydeducyAmount
			PayGateWayCallService.notifyCall(
					"13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount)
							.subtract(payDeductAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_055() {
		Logger.start(true, "一个订单多个商品,全额使用微信支付,支付网关回调成功,校验微信平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal discountAmount = new BigDecimal(new Random().nextInt(10))
					.add(BigDecimal.ONE);

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), discountAmount);

			Thread.sleep(10000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			// 验证
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, discountAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_056() {
		Logger.start(true, "一个订单多个商品,使用微信+用户余额,支付网关回调成功,校验微信平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = new BigDecimal(
					new Random().nextInt(100));

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal discountAmount = new BigDecimal(new Random().nextInt(10))
					.add(BigDecimal.ONE);

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), discountAmount);

			Thread.sleep(10000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			// 验证
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, discountAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_057() {
		Logger.start(true, "含有组合商品的订单,全额使用微信支付,支付网关回调成功,校验微信平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = placeOrder();

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			// 获取用户需要支付的金额
			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal discountAmount = new BigDecimal(new Random().nextInt(10))
					.add(BigDecimal.ONE);

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), discountAmount);

			Thread.sleep(10000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			// 验证
			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					orderList, discountAmount);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_058() {
		Logger.start(true, "一个订单多个商品,全额使用微信支付,支付网关回调成功前取消订单,校验微信平台补贴金额分摊");
		try {
			// 创建订单
			Logger.comment("前置数据准备");
			TradingServiceResp placeOrderResp = placeOrder4(false);

			List<Order> orderList = placeOrderResp.getOrderList();

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();
			BigDecimal useAccountAmount = BigDecimal.ZERO;

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			BigDecimal discountAmount = new BigDecimal(new Random().nextInt(10))
					.add(BigDecimal.ONE);

			// 取消所有子单
			orderList.forEach(o -> TradingCallService.cancelOrder(
					o.getOrderId(), CancelOrderTypeEnum.BUYER_CANCEL_ORDER,
					userId));

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue(), discountAmount);

			Thread.sleep(10000);

			for (Order o : orderList) {

				List<OrderDetailPo> orderDetailList = database
						.selectOrderDetailbyOrderId(o.getOrderId());
				for (OrderDetailPo detailPo : orderDetailList) {

					BigDecimal thirdPartyDiscount = detailPo
							.getThirdpartyDiscount();

					// 支付网关退款回调
					PayGateWayCallService.refundNotifyCall("15",
							thirdTradingId.toString(), userId.intValue(),
							thirdPartyDiscount);
				}
			}

			// 用户退款资金详情表（user_refund_fund_detail）
			UserRefundFundDetailPo userRefundFundDetailPo = database
					.selectUserRefundFundDetailByPaymentId(Long
							.valueOf(thirdTradingId));

			UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

			expectUserRefundFundDetailPo.setPaymentId(Long
					.valueOf(thirdTradingId));
			expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
			expectUserRefundFundDetailPo.setBizType(3);
			expectUserRefundFundDetailPo.setThirdpartyAmount(totalPrice
					.subtract(useAccountAmount));
			expectUserRefundFundDetailPo.setThirdpartyRefundStatus(4);
			expectUserRefundFundDetailPo.setRetryTimes(0);
			// expectUserRefundFundDetailPo.setMemo("0");

			RefundService.verifyUserRefundFundDetailDb(
					expectUserRefundFundDetailPo, userRefundFundDetailPo);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_059() {
		Logger.start(true, "使用余额支付定金订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();
			BigDecimal price = placeOrderResp.getOrderList().get(0)
					.getOrderPo().getEarnestAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(price);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTradeType(2);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(price,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_060() {
		Logger.start(true, "使用微信支付定金订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getMainOrderId();
			BigDecimal price = placeOrderResp.getOrderList().get(0)
					.getOrderPo().getEarnestAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("15");
			payReq.setTradeType(2);

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					price.subtract(BigDecimal.ZERO).toString(),
					userId.intValue());

			Thread.sleep(5000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_061() {
		Logger.start(true, "使用支付宝支付定金订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getMainOrderId();
			BigDecimal price = placeOrderResp.getOrderList().get(0)
					.getOrderPo().getEarnestAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			// payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");
			payReq.setTradeType(2);

			payReq.setParamExt("");
			payReq.setMemo("备注");
			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					price.subtract(BigDecimal.ZERO).toString(),
					userId.intValue());

			Thread.sleep(5000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_062() {
		Logger.start(true, "第三方支付+余额支付定金订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getMainOrderId();
			BigDecimal price = placeOrderResp.getOrderList().get(0)
					.getOrderPo().getEarnestAmount();
			BigDecimal useAccountAmount = new BigDecimal("0.01");

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("13");
			payReq.setTradeType(2);

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					price.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(3000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_063() {
		Logger.start(true, "支付定金后，继续支付定金");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			com.ymatou.iapi.optrade.resp.Order order = placeOrderResp
					.getOrderList().get(0);

			// 支付定金
			TradingCallService.payOrder(userId, order.getOrderPo()
					.getEarnestAmount(), tradingId, 2);
			List<Long> bookingConfirmOrderIds = new ArrayList<Long>();
			long orderId = order.getOrderId();
			bookingConfirmOrderIds.add(orderId);

			Logger.comment("前置数据准备结束");

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(placeOrderResp.getPayableAmount());
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTradeType(2);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.FAILED201, payReqCall.getCode(), "验证Code");
			Logger.verifyEquals("105", payReqCall.getBCode(), "验证bcode");
			Logger.verifyEquals("定金订单未二次确认不能进行全款支付", payReqCall.getMsg(),
					"验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_064() {
		Logger.start(true, "预付卡=定金，下单即支付，支付成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			PlaceOrderReq placeOrderReq = TradingCallService
					.buildStandPlaceOrderReq();
			
			
			
			OrderItemVo orderItemVo = placeOrderReq.getOrderGroups().get(0)
					.getOrders().get(0).getOrderItems().get(0);

			orderItemVo.setEarnestAmount(BigDecimal.ONE);
			orderItemVo.setBookingPromotionAmount(new BigDecimal("20.00"));

			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentStartTime(DateTime.now().plusDays(1).toDate());
			placeOrderReq.getOrderGroups().get(0).getOrders().get(0)
					.setPaymentEndTime(DateTime.now().plusDays(2).toDate());

			PrepaidCardVo prepaidCardVo = new PrepaidCardVo();

			prepaidCardVo.setCardAmount(orderItemVo.getEarnestAmount()
					.multiply(new BigDecimal(orderItemVo.getProductNum())));
			prepaidCardVo.setCardNo(PrepaidCardService.cardId1);

			placeOrderReq.setPrepaidCardVos(Arrays.asList(prepaidCardVo));

			TradingServiceResp placeOrderResp = TradingCallService
					.callPlaceOrderService(placeOrderReq);

			Logger.comment("前置数据准备结束");
			
			payReq.setTradeType(2);

			PaymentDetailPo paymentDetailPo = database
					.selectPaymentDetailByOrderId(placeOrderResp.getOrderList()
							.get(0).getOrderId());

			// 特殊定金订单，支付定金时使用的预付卡等于定金金额
			verifyDb(paymentDetailPo.getPaymentId(), BigDecimal.ZERO,
					placeOrderResp.getOrderList(), BigDecimal.ZERO,
					placeOrderReq);

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_065() {
		Logger.start(true, "使用余额支付全款订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			Order order = placeOrderResp.getOrderList().get(0);

			// 支付定金
			TradingCallService.payOrder(userId, order.getOrderPo()
					.getEarnestAmount(), tradingId, 2);
			List<Long> bookingConfirmOrderIds = new ArrayList<Long>();
			long orderId = order.getOrderId();
			bookingConfirmOrderIds.add(orderId);

			TradingServiceResp fullPaidResp = TradingPlaceEngageOrderCallService
					.placeOrderWithBookingConfirmOrderIds(bookingConfirmOrderIds);
			BigDecimal useAccountAmount = fullPaidResp.getPayableAmount();
			long fullPaidTradingId = fullPaidResp.getTradingId();
			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(useAccountAmount);
			payReq.setTradingId(fullPaidTradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTradeType(1);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					fullPaidResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(useAccountAmount,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_066() {
		Logger.start(true, "使用微信支付全款订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();
			com.ymatou.iapi.optrade.resp.Order order = placeOrderResp
					.getOrderList().get(0);
			BigDecimal payableAmount = placeOrderResp.getPayableAmount();

			// 支付定金
			TradingCallService.payOrder(userId, payableAmount, tradingId, 2);
			List<Long> bookingConfirmOrderIds = new ArrayList<Long>();
			long orderId = order.getOrderId();
			bookingConfirmOrderIds.add(orderId);

			TradingServiceResp fullPaidResp = TradingPlaceEngageOrderCallService
					.placeOrderWithBookingConfirmOrderIds(bookingConfirmOrderIds);
			BigDecimal fullPayableAmount = fullPaidResp.getPayableAmount();
			long fullPaidTradingId = fullPaidResp.getTradingId();
			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setCallbackUrl("www.ymtautotest.com");
			payReq.setUserId(userId);
			payReq.setTradingId(fullPaidTradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("123");
			payReq.setPayType("90");
			payReq.setTradeType(1);

			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					fullPayableAmount.subtract(BigDecimal.ZERO).toString(),
					userId.intValue());

			Thread.sleep(5000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					fullPaidResp.getOrderList(), BigDecimal.ZERO);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(payableAmount,
					afterAmount.subtract(beforeAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_067() {
		Logger.start(true, "余额支付定金，主单号包括两个订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder2Order(false);

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();
			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(price);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTradeType(2);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			//定金退还慢
			Thread.sleep(10000);
			
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(price,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_068() {
		Logger.start(true, "余额全款支付定金订单，主单号包括两个订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp engagePlaceOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder2Order(false);

			Long userId = engagePlaceOrderResp.getUserId();

			long tradingId = engagePlaceOrderResp.getMainOrderId();

			// 支付定金
			TradingCallService.payOrder(userId,
					engagePlaceOrderResp.getPayableAmount(), tradingId, 2);

			Logger.comment("前置数据准备结束");

			// 二次确认下单
			TradingServiceResp placeFullPaidOrderResp = TradingPlaceEngageOrderCallService
					.placeFullPaidOrder(engagePlaceOrderResp.getOrderList());

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(placeFullPaidOrderResp
					.getPayableAmount());
			payReq.setTradingId(placeFullPaidOrderResp.getTradingId());
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTradeType(1);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeFullPaidOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(
					placeFullPaidOrderResp.getPayableAmount(),
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_069() {
		Logger.start(true, "第三方支付定金，主单号包括两个订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder2Order(false);

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();
			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("15");
			payReq.setTradeType(2);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId),
					price.subtract(BigDecimal.ZERO).toString(),
					userId.intValue());

			Thread.sleep(3000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), BigDecimal.ZERO,
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_070() {
		Logger.start(true, "第三方全款支付定金订单，主单号包括两个订单");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp engagePlaceOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder2Order(false);

			Long userId = engagePlaceOrderResp.getUserId();

			long tradingId = engagePlaceOrderResp.getMainOrderId();

			// 支付定金
			TradingCallService.payOrder(userId,
					engagePlaceOrderResp.getPayableAmount(), tradingId, 2);

			Logger.comment("前置数据准备结束");

			// 二次确认下单
			TradingServiceResp placeFullPaidOrderResp = TradingPlaceEngageOrderCallService
					.placeFullPaidOrder(engagePlaceOrderResp.getOrderList());

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1).add(
					engagePlaceOrderResp.getPayableAmount());

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setTradingId(placeFullPaidOrderResp.getTradingId());
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("15");
			payReq.setTradeType(1);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("15",
					String.valueOf(thirdTradingId), placeFullPaidOrderResp
							.getPayableAmount().subtract(BigDecimal.ZERO)
							.toString(), userId.intValue());

			//为了等待退款入库，设置了超长等待时间
			Thread.sleep(15000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), BigDecimal.ZERO,
					placeFullPaidOrderResp.getOrderList(), BigDecimal.ZERO);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			Logger.comment(afterAmount.toPlainString());
			DataUtil.verifyDecimalEquals(BigDecimal.ZERO,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_071() {
		Logger.start(true, "定金订单全款支付后, 卖家未发货造成订单取消, 多赔一倍定金给买家");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp engagePlaceOrderResp = TradingPlaceEngageOrderCallService
					.placeEngageOrder(false);
			Long userId = engagePlaceOrderResp.getUserId();
			long sellerId = engagePlaceOrderResp.getOrderList().get(0)
					.getSellerId();
			long tradingId = engagePlaceOrderResp.getTradingId();
			long engageOrderId = engagePlaceOrderResp.getOrderList().get(0)
					.getOrderId();
			
			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 支付定金
			TradingCallService.payOrder(userId,
					engagePlaceOrderResp.getPayableAmount(), tradingId, 2);

			// 二次确认下单
			TradingServiceResp placeFullPaidOrderResp = TradingPlaceEngageOrderCallService
					.placeFullPaidOrder(engagePlaceOrderResp.getOrderList());

			// 修改全款最后支付时间
			OrderPo record = database
					.selectOrderbyOrderId(engageOrderId);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.add(Calendar.DAY_OF_MONTH, -10);

			record.setPaymentEndTime(calendar.getTime());
			database.orderMapper.updateByPrimaryKey(record);
			BigDecimal engageAmount = record.getEarnestAmount();
			BigDecimal fullPaidPayableAmount = placeFullPaidOrderResp
					.getPayableAmount();

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(fullPaidPayableAmount);
			payReq.setTradingId(placeFullPaidOrderResp.getTradingId());
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTradeType(1);
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();

			Thread.sleep(3000);

			TradingCallService.sellerAcceptOrder(sellerId, engageOrderId);

			//为了等待退款入库，设置了超长等待时间
			Thread.sleep(30000);

			// 支付后金额
			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);
			
			Logger.comment(beforeAmount.toPlainString());
			Logger.comment(afterAmount.toPlainString());

			// 卖家未发货造成订单取消, 多赔一倍定金给买家
			DataUtil.verifyDecimalEquals(
					engageAmount.negate(),
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");
			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_OrderPay_072() {
		Logger.start(true, "混合支付订单,使用折扣成功");
		try {
			// 创建订单
			Logger.comment("前置数据准备");

			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(false,
							BigDecimal.ZERO, userId,
							LogisticsTypeEnum.OVERSEAS_DELIVERY);

			Long userId = placeOrderResp.getUserId();

			long tradingId = placeOrderResp.getMainOrderId();

			BigDecimal price = placeOrderResp.getPayableAmount();

			Logger.comment("前置数据准备结束");

			// 支付前账户金额
			BigDecimal beforeAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			// 参数
			payReq.setUserId(userId);
			payReq.setCallbackUrl("www.ymatou.com");
			payReq.setUseAccountAmount(BigDecimal.TEN);
			payReq.setTradingId(tradingId);
			String tradingPassword = "abc123";
			payReq.setTradingPwd(tradingPassword);
			payReq.setUserIp("127.0.0.10");
			payReq.setBankId("");
			payReq.setPayType("10");
			payReq.setTerminalSource(TerminalSourceEnum.IOS);
			payReq.setParamExt("");
			payReq.setMemo("备注");

			// 发送请求
			payReqCall.setData(payReq);
			payReqCall.callService();
			
			Long thirdTradingId = payReqCall.getTradingId();

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId), price
							.subtract(BigDecimal.TEN)
							.toString(), userId.intValue());
			
			Thread.sleep(5000);

			Logger.verifyEquals(ECode.SUCCESS, payReqCall.getCode(), "验证Code");

			verifyDb(payReqCall.getTradingId(), payReq.getUseAccountAmount(),
					placeOrderResp.getOrderList(), BigDecimal.ZERO);

			BigDecimal afterAmount = AccountCallServiceV2.getAccountBalance(
					userId.intValue(), 1);

			DataUtil.verifyDecimalEquals(BigDecimal.TEN,
					beforeAmount.subtract(afterAmount), "校验用户账户余额扣减成功");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	public static void main(String[] args) {

		// BigDecimal[] orderDetailSubWeights = {new BigDecimal("600"), new
		// BigDecimal("144")};
		//
		// BigDecimal[] orderDetailSubDiscount = Utils
		// .apportionByWeights3(
		// new BigDecimal("9.00"),
		// orderDetailSubWeights);
		// System.out.println("123");

//		System.out.println(new BigDecimal("2175.00").divide(new BigDecimal(
//				"2185.00"), 2, BigDecimal.ROUND_DOWN));
//
//		System.out.println(new BigDecimal("2175.00")
//				.divide(new BigDecimal("2185.00"), 10, BigDecimal.ROUND_DOWN)
//				.multiply(new BigDecimal("1868.17"))
//				.setScale(2, BigDecimal.ROUND_DOWN));
	}
}
